You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2019/11/15 03:25:32 UTC
[dubbo] branch master updated: revert metadata related changes
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/master by this push:
new 50315fe revert metadata related changes
new 5f89039 mreged changes from metadata
50315fe is described below
commit 50315fe3d16a6b8d4e082a317e9606909c0c6159
Author: ken.lj <ke...@gmail.com>
AuthorDate: Fri Nov 15 11:20:14 2019 +0800
revert metadata related changes
---
.../configcenter/DynamicConfigurationFactory.java | 2 +-
.../dubbo/common/extension/ExtensionLoader.java | 24 +-
.../apache/dubbo/common/function/Predicates.java | 74 +++
.../org/apache/dubbo/common/function/Streams.java | 71 +++
.../apache/dubbo/common/utils/CollectionUtils.java | 21 +-
.../org/apache/dubbo/common/utils/StringUtils.java | 29 ++
.../apache/dubbo/config/context/ConfigManager.java | 4 +-
.../dubbo/common/function/PredicatesTest.java | 60 +++
.../apache/dubbo/common/function/StreamsTest.java | 57 +++
.../dubbo/common/utils/CollectionUtilsTest.java | 26 +-
.../dubbo/config/context/ConfigManagerTest.java | 223 +++++++++
dubbo-config/dubbo-config-api/pom.xml | 95 ++++
.../NacosDubboServiceConsumerBootstrap.java | 2 +-
.../ZookeeperDubboServiceConsumerBootstrap.java | 7 +-
dubbo-config/dubbo-config-spring/pom.xml | 6 +
.../AbstractAnnotationConfigBeanBuilder.java | 10 +-
.../AnnotatedInterfaceConfigBeanBuilder.java | 10 +-
.../AnnotationInjectedBeanPostProcessor.java | 548 ---------------------
.../AnnotationPropertyValuesAdapter.java | 5 +-
.../annotation/DubboConfigAliasPostProcessor.java | 2 +-
.../ReferenceAnnotationBeanPostProcessor.java | 9 +-
.../factory/annotation/ReferenceBeanBuilder.java | 12 +-
.../ServiceAnnotationBeanPostProcessor.java | 4 +-
.../factory/annotation/ServiceBeanNameBuilder.java | 4 +-
.../annotation/DubboComponentScanRegistrar.java | 4 +-
.../annotation/DubboConfigBindingRegistrar.java | 17 +-
.../annotation/DubboConfigBindingsRegistrar.java | 3 +
.../annotation/DubboConfigConfiguration.java | 51 +-
.../DubboConfigConfigurationRegistrar.java | 4 +-
.../DubboLifecycleComponentRegistrar.java | 2 +-
.../annotation/EnableDubboConfigBinding.java | 4 +
.../annotation/EnableDubboConfigBindings.java | 5 +-
...pertyDefaultValueDubboConfigBeanCustomizer.java | 2 +-
.../properties/DefaultDubboConfigBinder.java | 4 +-
.../spring/extension/SpringExtensionFactory.java | 4 +-
.../schema/AnnotationBeanDefinitionParser.java | 5 +-
.../spring/schema/DubboBeanDefinitionParser.java | 2 +-
.../spring/schema/DubboNamespaceHandler.java | 4 +-
.../util/AnnotatedBeanDefinitionRegistryUtils.java | 120 -----
.../dubbo/config/spring/util/AnnotationUtils.java | 310 ------------
...toryUtils.java => ApplicationContextUtils.java} | 56 +--
.../dubbo/config/spring/util/BeanRegistrar.java | 64 ---
.../config/spring/util/DubboAnnotationUtils.java | 150 ++++++
.../config/spring/util/PropertySourcesUtils.java | 115 -----
.../ReferenceAnnotationBeanPostProcessorTest.java | 19 +-
.../context/annotation/EnableDubboConfigTest.java | 3 +-
.../AnnotatedBeanDefinitionRegistryUtilsTest.java | 83 ----
.../spring/util/ApplicationContextUtilsTest.java} | 33 +-
.../config/spring/util/BeanFactoryUtilsTest.java | 111 -----
.../spring/util/PropertySourcesUtilsTest.java | 78 ---
dubbo-dependencies-bom/pom.xml | 11 +
.../DynamicConfigurationServiceNameMapping.java | 20 +-
.../dubbo/metadata/rest/RequestMetadata.java | 225 +++++++++
.../dubbo/metadata/rest/RestMethodMetadata.java | 187 +++++++
.../dubbo/metadata/rest/ServiceRestMetadata.java | 103 ++++
.../store/BaseWritableMetadataService.java | 5 +-
.../RemoteWritableMetadataServiceDelegate.java | 1 -
.../org/apache/dubbo/metadata/util/HttpUtils.java | 266 ++++++++++
...DynamicConfigurationServiceNameMappingTest.java | 10 +-
.../report/identifier/MetadataIdentifierTest.java | 1 -
.../store/InMemoryWritableMetadataServiceTest.java | 1 -
.../store/RemoteWritableMeatadataServiceTest.java | 3 -
dubbo-metadata/dubbo-metadata-processor/pom.xml | 161 ++++++
.../AbstractServiceAnnotationProcessor.java | 108 ++++
.../processing/ClassPathMetadataStorage.java | 105 ++++
...rviceDefinitionMetadataAnnotationProcessor.java | 60 +++
.../builder/ArrayTypeDefinitionBuilder.java | 50 ++
.../builder/CollectionTypeDefinitionBuilder.java | 61 +++
.../builder/DeclaredTypeDefinitionBuilder.java | 49 ++
.../builder/EnumTypeDefinitionBuilder.java | 55 +++
.../builder/GeneralTypeDefinitionBuilder.java | 65 +++
.../builder/MapTypeDefinitionBuilder.java | 62 +++
.../builder/MethodDefinitionBuilder.java | 53 ++
.../builder/PrimitiveTypeDefinitionBuilder.java | 48 ++
.../builder/ServiceDefinitionBuilder.java | 56 +++
.../builder/SimpleTypeDefinitionBuilder.java | 49 ++
.../processing/builder/TypeDefinitionBuilder.java | 95 ++++
.../AbstractAnnotatedMethodParameterProcessor.java | 52 ++
.../rest/AbstractServiceRestMetadataProcessor.java | 234 +++++++++
.../rest/AnnotatedMethodParameterProcessor.java | 64 +++
.../rest/DefaultServiceRestMetadataProcessor.java | 59 +++
.../ServiceRestMetadataAnnotationProcessor.java | 88 ++++
.../rest/ServiceRestMetadataProcessor.java | 55 +++
.../rest/ServiceRestMetadataStorage.java | 66 +++
.../rest/jaxrs/DefaultValueParameterProcessor.java | 78 +++
.../rest/jaxrs/FormParamParameterProcessor.java | 21 +-
.../rest/jaxrs/HeaderParamParameterProcessor.java | 50 ++
.../jaxrs/JAXRSServiceRestMetadataProcessor.java | 113 +++++
.../rest/jaxrs/MatrixParamParameterProcessor.java | 23 +-
.../jaxrs/ParamAnnotationParameterProcessor.java | 38 ++
.../rest/jaxrs/QueryParamParameterProcessor.java | 23 +-
...bstractRequestAnnotationParameterProcessor.java | 69 +++
.../springmvc/RequestHeaderParameterProcessor.java | 41 ++
.../springmvc/RequestParamParameterProcessor.java | 44 ++
.../SpringMvcServiceRestMetadataProcessor.java | 157 ++++++
.../processing/util/AnnotationUtils.java | 233 +++++++++
.../annotation/processing/util/FieldUtils.java | 146 ++++++
.../annotation/processing/util/LoggerUtils.java | 34 +-
.../annotation/processing/util/MemberUtils.java | 94 ++++
.../annotation/processing/util/MethodUtils.java | 155 ++++++
.../processing/util/ServiceAnnotationUtils.java | 121 +++++
.../annotation/processing/util/TypeUtils.java | 382 ++++++++++++++
...tation.processing.builder.TypeDefinitionBuilder | 7 +
...ocessing.rest.AnnotatedMethodParameterProcessor | 10 +
...on.processing.rest.ServiceRestMetadataProcessor | 3 +
.../services/javax.annotation.processing.Processor | 2 +
.../AbstractAnnotationProcessingTest.java | 69 +++
.../builder/ArrayTypeDefinitionBuilderTest.java | 121 +++++
.../CollectionTypeDefinitionBuilderTest.java | 105 ++++
.../builder/EnumTypeDefinitionBuilderTest.java | 67 +++
.../builder/GeneralTypeDefinitionBuilderTest.java | 67 +++
.../builder/MapTypeDefinitionBuilderTest.java | 134 +++++
.../PrimitiveTypeDefinitionBuilderTest.java | 130 +++++
.../builder/ServiceDefinitionBuilderTest.java | 64 +++
.../builder/SimpleTypeDefinitionBuilderTest.java | 146 ++++++
.../processing/model/ArrayTypeModel.java | 27 +-
.../processing/model/CollectionTypeModel.java | 35 +-
.../annotation/processing/model/Color.java | 35 +-
.../annotation/processing/model/MapTypeModel.java | 32 +-
.../annotation/processing/model/Model.java | 89 ++++
.../processing/model/PrimitiveTypeModel.java | 62 ++-
.../processing/model/SimpleTypeModel.java | 161 ++++++
.../AnnotatedMethodParameterProcessorTest.java | 59 +++
.../processing/util/AnnotationUtilsTest.java | 231 +++++++++
.../annotation/processing/util/FieldUtilsTest.java | 259 ++++++++++
.../processing/util/LoggerUtilsTest.java | 39 +-
.../processing/util/MemberUtilsTest.java | 113 +++++
.../processing/util/MethodUtilsTest.java | 195 ++++++++
.../util/ServiceAnnotationUtilsTest.java | 136 +++++
.../annotation/processing/util/TypeUtilsTest.java | 467 ++++++++++++++++++
.../org/apache/dubbo/metadata/tools/Ancestor.java | 26 +-
.../org/apache/dubbo/metadata/tools/Compiler.java | 116 +++++
.../apache/dubbo/metadata/tools/CompilerTest.java | 30 +-
.../dubbo/metadata/tools/DefaultTestService.java | 63 +++
.../dubbo/metadata/tools/GenericTestService.java | 31 +-
.../org/apache/dubbo/metadata/tools/Parent.java | 54 +-
.../apache/dubbo/metadata/tools/RestService.java | 35 +-
.../dubbo/metadata/tools/RestServiceTest.java | 28 +-
.../dubbo/metadata/tools/SpringRestService.java | 97 ++++
.../metadata/tools/SpringRestServiceTest.java | 26 +-
.../dubbo/metadata/tools/StandardRestService.java | 107 ++++
.../metadata/tools/StandardRestServiceTest.java | 26 +-
.../apache/dubbo/metadata/tools/TestProcessor.java | 46 ++
.../apache/dubbo/metadata/tools/TestService.java | 53 +-
.../dubbo/metadata/tools/TestServiceImpl.java | 51 ++
.../java/org/apache/dubbo/metadata/tools/User.java | 61 +++
dubbo-metadata/pom.xml | 1 +
.../proxy/MetadataServiceProxyFactory.java | 3 +-
.../metadata/proxy/RemoteMetadataServiceProxy.java | 6 +-
149 files changed, 8727 insertions(+), 1906 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java
index b010964..1c25a40 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfigurationFactory.java
@@ -25,7 +25,7 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad
/**
* The factory interface to create the instance of {@link DynamicConfiguration}
*/
-@SPI("nop")
+@SPI("file") // 2.7.5 change the default SPI implementation
public interface DynamicConfigurationFactory {
DynamicConfiguration getDynamicConfiguration(URL url);
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
index 6741e11..b0418d4 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/extension/ExtensionLoader.java
@@ -19,6 +19,7 @@ package org.apache.dubbo.common.extension;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.context.Lifecycle;
import org.apache.dubbo.common.extension.support.ActivateComparator;
+import org.apache.dubbo.common.lang.Prioritized;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ArrayUtils;
@@ -40,7 +41,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -49,17 +51,17 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.regex.Pattern;
+import static java.util.Collections.sort;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REMOVE_VALUE_PREFIX;
/**
- *
* {@link org.apache.dubbo.rpc.model.ApplicationModel}, {@code DubboBootstrap} and this class are
* at present designed to be singleton or static (by itself totally static or uses some static fields).
* So the instances returned from them are of process or classloader scope. If you want to support
* multiple dubbo servers in a single process, you may need to refactor these three classes.
- *
+ * <p>
* Load dubbo extensions
* <ul>
* <li>auto inject dependency extension </li>
@@ -404,7 +406,7 @@ public class ExtensionLoader<T> {
* @return non-null
*/
public T getOrDefaultExtension(String name) {
- return containsExtension(name) ? getExtension(name) : getDefaultExtension();
+ return containsExtension(name) ? getExtension(name) : getDefaultExtension();
}
/**
@@ -432,14 +434,16 @@ public class ExtensionLoader<T> {
}
public Set<T> getSupportedExtensionInstances() {
- Set<T> instances = new HashSet<>();
+ List<T> instances = new LinkedList<>();
Set<String> supportedExtensions = getSupportedExtensions();
if (CollectionUtils.isNotEmpty(supportedExtensions)) {
for (String name : supportedExtensions) {
instances.add(getExtension(name));
}
}
- return instances;
+ // sort the Prioritized instances
+ sort(instances, Prioritized.COMPARATOR);
+ return new LinkedHashSet<>(instances);
}
/**
@@ -712,7 +716,7 @@ public class ExtensionLoader<T> {
/**
* synchronized in getExtensionClasses
- * */
+ */
private Map<String, Class<?>> loadExtensionClasses() {
cacheDefaultExtensionName();
@@ -759,7 +763,7 @@ public class ExtensionLoader<T> {
try {
Enumeration<java.net.URL> urls = null;
ClassLoader classLoader = findClassLoader();
-
+
// try to load from ExtensionLoader's ClassLoader first
if (extensionLoaderClassLoaderFirst) {
ClassLoader extensionLoaderClassLoader = ExtensionLoader.class.getClassLoader();
@@ -767,8 +771,8 @@ public class ExtensionLoader<T> {
urls = extensionLoaderClassLoader.getResources(fileName);
}
}
-
- if(urls == null || !urls.hasMoreElements()) {
+
+ if (urls == null || !urls.hasMoreElements()) {
if (classLoader != null) {
urls = classLoader.getResources(fileName);
} else {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java
new file mode 100644
index 0000000..445b169
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Predicates.java
@@ -0,0 +1,74 @@
+/*
+ * 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 org.apache.dubbo.common.function;
+
+import java.util.function.Predicate;
+
+import static java.util.stream.Stream.of;
+
+/**
+ * The utilities class for Java {@link Predicate}
+ *
+ * @since 2.7.5
+ */
+public interface Predicates {
+
+ Predicate[] EMPTY_ARRAY = new Predicate[0];
+
+ /**
+ * {@link Predicate} always return <code>true</code>
+ *
+ * @param <T> the type to test
+ * @return <code>true</code>
+ */
+ static <T> Predicate<T> alwaysTrue() {
+ return e -> true;
+ }
+
+ /**
+ * {@link Predicate} always return <code>false</code>
+ *
+ * @param <T> the type to test
+ * @return <code>false</code>
+ */
+ static <T> Predicate<T> alwaysFalse() {
+ return e -> false;
+ }
+
+ /**
+ * a composed predicate that represents a short-circuiting logical AND of {@link Predicate predicates}
+ *
+ * @param predicates {@link Predicate predicates}
+ * @param <T> the type to test
+ * @return non-null
+ */
+ static <T> Predicate<T> and(Predicate<T>... predicates) {
+ return of(predicates).reduce((a, b) -> a.and(b)).orElseGet(Predicates::alwaysTrue);
+ }
+
+ /**
+ * a composed predicate that represents a short-circuiting logical OR of {@link Predicate predicates}
+ *
+ * @param predicates {@link Predicate predicates}
+ * @param <T> the detected type
+ * @return non-null
+ */
+ static <T> Predicate<T> or(Predicate<T>... predicates) {
+ return of(predicates).reduce((a, b) -> a.or(b)).orElse(e -> true);
+ }
+
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java
new file mode 100644
index 0000000..65e4fa6
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/function/Streams.java
@@ -0,0 +1,71 @@
+/*
+ * 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 org.apache.dubbo.common.function;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toList;
+import static java.util.stream.StreamSupport.stream;
+import static org.apache.dubbo.common.function.Predicates.and;
+import static org.apache.dubbo.common.function.Predicates.or;
+
+/**
+ * The utilities class for {@link Stream}
+ *
+ * @since 2.7.5
+ */
+public interface Streams {
+
+ static <T, S extends Iterable<T>> Stream<T> filterStream(S values, Predicate<T> predicate) {
+ return stream(values.spliterator(), false).filter(predicate);
+ }
+
+ static <T, S extends Iterable<T>> List<T> filterList(S values, Predicate<T> predicate) {
+ return filterStream(values, predicate).collect(toList());
+ }
+
+ static <T, S extends Iterable<T>> Set<T> filterSet(S values, Predicate<T> predicate) {
+ // new Set with insertion order
+ return filterStream(values, predicate).collect(LinkedHashSet::new, Set::add, Set::addAll);
+ }
+
+ static <T, S extends Iterable<T>> S filter(S values, Predicate<T> predicate) {
+ final boolean isSet = Set.class.isAssignableFrom(values.getClass());
+ return (S) (isSet ? filterSet(values, predicate) : filterList(values, predicate));
+ }
+
+ static <T, S extends Iterable<T>> S filterAll(S values, Predicate<T>... predicates) {
+ return filter(values, and(predicates));
+ }
+
+ static <T, S extends Iterable<T>> S filterAny(S values, Predicate<T>... predicates) {
+ return filter(values, or(predicates));
+ }
+
+ static <T> T filterFirst(Iterable<T> values, Predicate<T>... predicates) {
+ return stream(values.spliterator(), false)
+ .filter(and(predicates))
+ .findFirst()
+ .orElse(null);
+ }
+}
+
+
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java
index 4e924b3..28e9821 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/CollectionUtils.java
@@ -21,8 +21,14 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.unmodifiableSet;
public class CollectionUtils {
@@ -173,7 +179,7 @@ public class CollectionUtils {
public static Map<String, String> toStringMap(String... pairs) {
Map<String, String> parameters = new HashMap<>();
- if(ArrayUtils.isEmpty(pairs)){
+ if (ArrayUtils.isEmpty(pairs)) {
return parameters;
}
@@ -221,4 +227,17 @@ public class CollectionUtils {
return !isEmptyMap(map);
}
+ /**
+ * Convert to multiple values to be {@link LinkedHashSet}
+ *
+ * @param values one or more values
+ * @param <T> the type of <code>values</code>
+ * @return read-only {@link Set}
+ */
+ public static <T> Set<T> ofSet(T... values) {
+ if (values == null || values.length < 1) {
+ return emptySet();
+ }
+ return unmodifiableSet(new LinkedHashSet<>(asList(values)));
+ }
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
index c49d106..c904800 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
@@ -33,6 +33,7 @@ import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import static java.lang.String.valueOf;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.DOT_REGEX;
@@ -58,6 +59,34 @@ public final class StringUtils {
private static final Pattern INT_PATTERN = Pattern.compile("^\\d+$");
private static final int PAD_LIMIT = 8192;
+ /**
+ * @since 2.7.5
+ */
+ public static final char EQUAL_CHAR = '=';
+
+ public static final String EQUAL = valueOf(EQUAL_CHAR);
+
+ public static final char AND_CHAR = '&';
+
+ public static final String AND = valueOf(AND_CHAR);
+
+ public static final char SEMICOLON_CHAR = ';';
+
+ public static final String SEMICOLON = valueOf(SEMICOLON_CHAR);
+
+ public static final char QUESTION_MASK_CHAR = '?';
+
+ public static final String QUESTION_MASK = valueOf(QUESTION_MASK_CHAR);
+
+ public static final char SLASH_CHAR = '/';
+
+ public static final String SLASH = valueOf(SLASH_CHAR);
+
+ /**
+ * The empty value
+ */
+ public static final String EMPTY_VALUE = "";
+
private StringUtils() {
}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
index b7efb4f..f2936ec 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java
@@ -62,9 +62,11 @@ import static org.apache.dubbo.config.Constants.PROTOCOLS_SUFFIX;
import static org.apache.dubbo.config.Constants.REGISTRIES_SUFFIX;
public class ConfigManager extends LifecycleAdapter implements FrameworkExt {
- public static final String NAME = "config";
+
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
+ public static final String NAME = "config";
+
private final Map<String, Map<String, AbstractConfig>> configsCache = newMap();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/function/PredicatesTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/function/PredicatesTest.java
new file mode 100644
index 0000000..d042e64
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/function/PredicatesTest.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.dubbo.common.function;
+
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.function.Predicates.alwaysFalse;
+import static org.apache.dubbo.common.function.Predicates.alwaysTrue;
+import static org.apache.dubbo.common.function.Predicates.and;
+import static org.apache.dubbo.common.function.Predicates.or;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link Predicates} Test
+ *
+ * @since 2.7.5
+ */
+public class PredicatesTest {
+
+ @Test
+ public void testAlwaysTrue() {
+ assertTrue(alwaysTrue().test(null));
+ }
+
+ @Test
+ public void testAlwaysFalse() {
+ assertFalse(alwaysFalse().test(null));
+ }
+
+ @Test
+ public void testAnd() {
+ assertTrue(and(alwaysTrue(), alwaysTrue(), alwaysTrue()).test(null));
+ assertFalse(and(alwaysFalse(), alwaysFalse(), alwaysFalse()).test(null));
+ assertFalse(and(alwaysTrue(), alwaysFalse(), alwaysFalse()).test(null));
+ assertFalse(and(alwaysTrue(), alwaysTrue(), alwaysFalse()).test(null));
+ }
+
+ @Test
+ public void testOr() {
+ assertTrue(or(alwaysTrue(), alwaysTrue(), alwaysTrue()).test(null));
+ assertTrue(or(alwaysTrue(), alwaysTrue(), alwaysFalse()).test(null));
+ assertTrue(or(alwaysTrue(), alwaysFalse(), alwaysFalse()).test(null));
+ assertFalse(or(alwaysFalse(), alwaysFalse(), alwaysFalse()).test(null));
+ }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/function/StreamsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/function/StreamsTest.java
new file mode 100644
index 0000000..d55a009
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/function/StreamsTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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 org.apache.dubbo.common.function;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+import static java.util.stream.Collectors.toList;
+import static org.apache.dubbo.common.function.Streams.filterList;
+import static org.apache.dubbo.common.function.Streams.filterSet;
+import static org.apache.dubbo.common.function.Streams.filterStream;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link Streams} Test
+ *
+ * @since 2.7.5
+ */
+public class StreamsTest {
+
+ @Test
+ public void testFilterStream() {
+ Stream<Integer> stream = filterStream(asList(1, 2, 3, 4, 5), i -> i % 2 == 0);
+ assertEquals(asList(2, 4), stream.collect(toList()));
+ }
+
+ @Test
+ public void testFilterList() {
+ List<Integer> list = filterList(asList(1, 2, 3, 4, 5), i -> i % 2 == 0);
+ assertEquals(asList(2, 4), list);
+ }
+
+ @Test
+ public void testFilterSet() {
+ Set<Integer> set = filterSet(asList(1, 2, 3, 4, 5), i -> i % 2 == 0);
+ assertEquals(new LinkedHashSet<>(asList(2, 4)), set);
+ }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java
index 22d8d92..36af51d 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/CollectionUtilsTest.java
@@ -24,21 +24,25 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.singleton;
import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty;
+import static org.apache.dubbo.common.utils.CollectionUtils.ofSet;
import static org.apache.dubbo.common.utils.CollectionUtils.toMap;
import static org.apache.dubbo.common.utils.CollectionUtils.toStringMap;
-import static java.util.Collections.emptyList;
-import static java.util.Collections.singleton;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
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.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class CollectionUtilsTest {
@@ -195,4 +199,20 @@ public class CollectionUtilsTest {
public void testIsNotEmpty() throws Exception {
assertThat(isNotEmpty(singleton("a")), is(true));
}
+
+ @Test
+ public void testOfSet() {
+ Set<String> set = ofSet();
+ assertEquals(emptySet(), set);
+
+ set = ofSet(((String[]) null));
+ assertEquals(emptySet(), set);
+
+ set = ofSet("A", "B", "C");
+ Set<String> expectedSet = new LinkedHashSet<>();
+ expectedSet.add("A");
+ expectedSet.add("B");
+ expectedSet.add("C");
+ assertEquals(expectedSet, set);
+ }
}
\ No newline at end of file
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
new file mode 100644
index 0000000..5a40296
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/config/context/ConfigManagerTest.java
@@ -0,0 +1,223 @@
+/*
+ * 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 org.apache.dubbo.config.context;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ConfigCenterConfig;
+import org.apache.dubbo.config.ConsumerConfig;
+import org.apache.dubbo.config.MetricsConfig;
+import org.apache.dubbo.config.ModuleConfig;
+import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ProviderConfig;
+import org.apache.dubbo.config.RegistryConfig;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collection;
+
+import static java.util.Arrays.asList;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
+import static org.apache.dubbo.rpc.model.ApplicationModel.getConfigManager;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link ConfigManager} Test
+ *
+ * @since 2.7.5
+ */
+public class ConfigManagerTest {
+
+ private ConfigManager configManager = getConfigManager();
+
+ @BeforeEach
+ public void init() {
+ configManager.clear();
+ }
+
+ @Test
+ public void testDefaultValues() {
+ // assert single
+ assertFalse(configManager.getApplication().isPresent());
+ assertFalse(configManager.getMonitor().isPresent());
+ assertFalse(configManager.getModule().isPresent());
+ assertFalse(configManager.getMetrics().isPresent());
+
+ // providers and consumers
+ assertFalse(configManager.getDefaultProvider().isPresent());
+ assertFalse(configManager.getDefaultConsumer().isPresent());
+ assertTrue(configManager.getProviders().isEmpty());
+ assertTrue(configManager.getConsumers().isEmpty());
+
+ // protocols
+ assertTrue(configManager.getProtocols().isEmpty());
+ assertTrue(configManager.getDefaultProtocols().isEmpty());
+ assertTrue(configManager.getProtocolIds().isEmpty());
+
+ // registries
+ assertTrue(configManager.getRegistries().isEmpty());
+ assertTrue(configManager.getDefaultRegistries().isEmpty());
+ assertTrue(configManager.getRegistryIds().isEmpty());
+
+ // services and references
+ assertTrue(configManager.getServices().isEmpty());
+ assertTrue(configManager.getReferences().isEmpty());
+
+ // config centers
+ assertTrue(configManager.getConfigCenters().isEmpty());
+
+ // metadata
+ assertTrue(configManager.getMetadataConfigs().isEmpty());
+ }
+
+ // Test ApplicationConfig correlative methods
+ @Test
+ public void testApplicationConfig() {
+ ApplicationConfig config = new ApplicationConfig();
+ configManager.setApplication(config);
+ assertTrue(configManager.getApplication().isPresent());
+ assertEquals(config, configManager.getApplication().get());
+ assertThrows(IllegalStateException.class, () -> {
+ configManager.setApplication(new ApplicationConfig("test"));
+ });
+ }
+
+ // Test MonitorConfig correlative methods
+ @Test
+ public void testMonitorConfig() {
+ MonitorConfig monitorConfig = new MonitorConfig();
+ monitorConfig.setGroup("test");
+ configManager.setMonitor(monitorConfig);
+ assertTrue(configManager.getMonitor().isPresent());
+ assertEquals(monitorConfig, configManager.getMonitor().get());
+ assertThrows(IllegalStateException.class, () -> {
+ configManager.setMonitor(new MonitorConfig());
+ });
+ }
+
+ // Test MonitorConfig correlative methods
+ @Test
+ public void tesModuleConfig() {
+ ModuleConfig config = new ModuleConfig();
+ configManager.setModule(config);
+ assertTrue(configManager.getModule().isPresent());
+ assertEquals(config, configManager.getModule().get());
+ assertThrows(IllegalStateException.class, () -> {
+ configManager.setModule(new ModuleConfig("test"));
+ });
+ }
+
+ // Test MetricsConfig correlative methods
+ @Test
+ public void tesMetricsConfig() {
+ MetricsConfig config = new MetricsConfig();
+ configManager.setMetrics(config);
+ assertTrue(configManager.getMetrics().isPresent());
+ assertEquals(config, configManager.getMetrics().get());
+ assertThrows(IllegalStateException.class, () -> {
+ MetricsConfig metricsConfig = new MetricsConfig();
+ metricsConfig.setPort("101");
+ configManager.setMetrics(metricsConfig);
+ });
+ }
+
+ // Test ProviderConfig correlative methods
+ @Test
+ public void testProviderConfig() {
+ ProviderConfig config = new ProviderConfig();
+ configManager.addProviders(asList(config, null));
+ Collection<ProviderConfig> configs = configManager.getProviders();
+ assertEquals(1, configs.size());
+ assertEquals(config, configs.iterator().next());
+ assertFalse(configManager.getDefaultProvider().isPresent());
+
+ config.setId(DEFAULT_KEY);
+ configManager.addProvider(config);
+ assertTrue(configManager.getDefaultProvider().isPresent());
+ configs = configManager.getProviders();
+ assertEquals(2, configs.size());
+ }
+
+ // Test ConsumerConfig correlative methods
+ @Test
+ public void testConsumerConfig() {
+ ConsumerConfig config = new ConsumerConfig();
+ configManager.addConsumers(asList(config, null));
+ Collection<ConsumerConfig> configs = configManager.getConsumers();
+ assertEquals(1, configs.size());
+ assertEquals(config, configs.iterator().next());
+ assertFalse(configManager.getDefaultConsumer().isPresent());
+
+ config.setId(DEFAULT_KEY);
+ configManager.addConsumer(config);
+ assertTrue(configManager.getDefaultConsumer().isPresent());
+ configs = configManager.getConsumers();
+ assertEquals(2, configs.size());
+ }
+
+ // Test ProtocolConfig correlative methods
+ @Test
+ public void testProtocolConfig() {
+ ProtocolConfig config = new ProtocolConfig();
+ configManager.addProtocols(asList(config, null));
+ Collection<ProtocolConfig> configs = configManager.getProtocols();
+ assertEquals(1, configs.size());
+ assertEquals(config, configs.iterator().next());
+ assertFalse(configManager.getDefaultProtocols().isEmpty());
+ }
+
+ // Test RegistryConfig correlative methods
+ @Test
+ public void testRegistryConfig() {
+ RegistryConfig config = new RegistryConfig();
+ configManager.addRegistries(asList(config, null));
+ Collection<RegistryConfig> configs = configManager.getRegistries();
+ assertEquals(1, configs.size());
+ assertEquals(config, configs.iterator().next());
+ assertFalse(configManager.getDefaultRegistries().isEmpty());
+ }
+
+ // Test ConfigCenterConfig correlative methods
+ @Test
+ public void testConfigCenterConfig() {
+ ConfigCenterConfig config = new ConfigCenterConfig();
+ configManager.addConfigCenters(asList(config, null));
+ Collection<ConfigCenterConfig> configs = configManager.getConfigCenters();
+ assertEquals(1, configs.size());
+ assertEquals(config, configs.iterator().next());
+ }
+
+ @Test
+ public void testAddConfig() {
+ configManager.addConfig(new ApplicationConfig());
+ configManager.addConfig(new ProviderConfig());
+ configManager.addConfig(new ProtocolConfig());
+
+ assertTrue(configManager.getApplication().isPresent());
+ assertFalse(configManager.getProviders().isEmpty());
+ assertFalse(configManager.getProtocols().isEmpty());
+ }
+
+ @Test
+ public void testRefreshAll() {
+ configManager.refreshAll();
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml
index 9183a3e..5937993 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -69,27 +69,122 @@
<!-- FIXME, we shouldn't rely on these modules, even in test scope -->
<dependency>
<groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-rpc-dubbo</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
+
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rmi</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-rpc-hessian</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-serialization-hessian2</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-multicast</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-registry-zookeeper</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-registry-nacos</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-registry-eureka</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-registry-etcd3</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-registry-consul</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata-report-zookeeper</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata-report-etcd</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata-report-nacos</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata-report-redis</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-configcenter-zookeeper</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</project>
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
index 552fb20..b91659d 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/NacosDubboServiceConsumerBootstrap.java
@@ -36,7 +36,7 @@ public class NacosDubboServiceConsumerBootstrap {
// Zookeeper
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service&subscribed.services=dubbo-nacos-provider-demo"))
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo"))
- .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=service-provider"))
+ .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo"))
.metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
index ed421b1..9b0d866 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/ZookeeperDubboServiceConsumerBootstrap.java
@@ -32,18 +32,17 @@ public class ZookeeperDubboServiceConsumerBootstrap {
.registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service&subscribed-services=zookeeper-dubbo-provider"))
.reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
- .start()
- .await();
+ .start();
EchoService echoService = bootstrap.getCache().get(EchoService.class);
UserService userService = bootstrap.getCache().get(UserService.class);
- for (int i = 0; i < 500; i++) {
+ for (int i = 0; i < 5; i++) {
Thread.sleep(2000L);
System.out.println(echoService.echo("Hello,World"));
System.out.println(userService.getUser(i * 1L));
}
-
+ bootstrap.stop();
}
}
diff --git a/dubbo-config/dubbo-config-spring/pom.xml b/dubbo-config/dubbo-config-spring/pom.xml
index aa4b0b2..12bd8d2 100644
--- a/dubbo-config/dubbo-config-spring/pom.xml
+++ b/dubbo-config/dubbo-config-spring/pom.xml
@@ -56,6 +56,12 @@
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
+
+ <dependency>
+ <groupId>com.alibaba.spring</groupId>
+ <artifactId>spring-context-support</artifactId>
+ </dependency>
+
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-default</artifactId>
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
index 670d568..01186af 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationConfigBeanBuilder.java
@@ -30,8 +30,8 @@ import org.springframework.util.Assert;
import java.lang.annotation.Annotation;
import java.util.List;
-import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getBeans;
-import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getNullableBean;
+import static com.alibaba.spring.util.BeanFactoryUtils.getBeans;
+import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
/**
* Abstract Configurable {@link Annotation} Bean Builder
@@ -132,7 +132,7 @@ abstract class AbstractAnnotationConfigBeanBuilder<A extends Annotation, B exten
String monitorBeanName = resolveMonitorConfigBeanName(annotation);
- MonitorConfig monitorConfig = getNullableBean(applicationContext, monitorBeanName, MonitorConfig.class);
+ MonitorConfig monitorConfig = getOptionalBean(applicationContext, monitorBeanName, MonitorConfig.class);
bean.setMonitor(monitorConfig);
@@ -143,7 +143,7 @@ abstract class AbstractAnnotationConfigBeanBuilder<A extends Annotation, B exten
String applicationConfigBeanName = resolveApplicationConfigBeanName(annotation);
ApplicationConfig applicationConfig =
- getNullableBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
+ getOptionalBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
bean.setApplication(applicationConfig);
@@ -154,7 +154,7 @@ abstract class AbstractAnnotationConfigBeanBuilder<A extends Annotation, B exten
String moduleConfigBeanName = resolveModuleConfigBeanName(annotation);
ModuleConfig moduleConfig =
- getNullableBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
+ getOptionalBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
bean.setModule(moduleConfig);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java
index 97b6655..be951ae 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotatedInterfaceConfigBeanBuilder.java
@@ -31,8 +31,8 @@ import org.springframework.util.Assert;
import java.lang.annotation.Annotation;
import java.util.List;
-import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getBeans;
-import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getNullableBean;
+import static com.alibaba.spring.util.BeanFactoryUtils.getBeans;
+import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
/**
* An Abstract Builder to build {@link AbstractInterfaceConfig Interface Config} Bean that annotated
@@ -133,7 +133,7 @@ public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInte
String monitorBeanName = resolveMonitorConfigBeanName(attributes);
- MonitorConfig monitorConfig = getNullableBean(applicationContext, monitorBeanName, MonitorConfig.class);
+ MonitorConfig monitorConfig = getOptionalBean(applicationContext, monitorBeanName, MonitorConfig.class);
configBean.setMonitor(monitorConfig);
@@ -144,7 +144,7 @@ public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInte
String applicationConfigBeanName = resolveApplicationConfigBeanName(attributes);
ApplicationConfig applicationConfig =
- getNullableBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
+ getOptionalBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
configBean.setApplication(applicationConfig);
@@ -155,7 +155,7 @@ public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInte
String moduleConfigBeanName = resolveModuleConfigBeanName(attributes);
ModuleConfig moduleConfig =
- getNullableBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
+ getOptionalBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
configBean.setModule(moduleConfig);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
deleted file mode 100644
index cf87cf2..0000000
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationInjectedBeanPostProcessor.java
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.beans.factory.annotation;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.PropertyValues;
-import org.springframework.beans.factory.BeanClassLoaderAware;
-import org.springframework.beans.factory.BeanCreationException;
-import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.BeanFactoryAware;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
-import org.springframework.beans.factory.annotation.InjectionMetadata;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
-import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
-import org.springframework.beans.factory.support.MergedBeanDefinitionPostProcessor;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.context.EnvironmentAware;
-import org.springframework.core.Ordered;
-import org.springframework.core.PriorityOrdered;
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.env.Environment;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
-import org.springframework.util.StringUtils;
-
-import java.beans.PropertyDescriptor;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.getMergedAttributes;
-import static org.springframework.core.BridgeMethodResolver.findBridgedMethod;
-import static org.springframework.core.BridgeMethodResolver.isVisibilityBridgeMethodPair;
-
-/**
- * Abstract generic {@link BeanPostProcessor} implementation for customized annotation that annotated injected-object.
- * <p>
- *
- * @revision 2.7.3 Uses {@link AnnotationAttributes} instead of {@link Annotation}
- * @since 2.6.6
- */
-public abstract class AnnotationInjectedBeanPostProcessor extends
- InstantiationAwareBeanPostProcessorAdapter implements MergedBeanDefinitionPostProcessor, PriorityOrdered,
- BeanFactoryAware, BeanClassLoaderAware, EnvironmentAware, DisposableBean {
-
- private final static int CACHE_SIZE = Integer.getInteger("", 32);
-
- private final Log logger = LogFactory.getLog(getClass());
-
- private final Class<? extends Annotation>[] annotationTypes;
-
- private final ConcurrentMap<String, AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata> injectionMetadataCache =
- new ConcurrentHashMap<String, AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata>(CACHE_SIZE);
-
- private final ConcurrentMap<String, Object> injectedObjectsCache = new ConcurrentHashMap<>(CACHE_SIZE);
-
- private ConfigurableListableBeanFactory beanFactory;
-
- private Environment environment;
-
- private ClassLoader classLoader;
-
- /**
- * make sure higher priority than {@link AutowiredAnnotationBeanPostProcessor}
- *
- * @revision 2.7.3
- */
- private int order = Ordered.LOWEST_PRECEDENCE - 3;
-
- /**
- * @param annotationTypes the multiple types of {@link Annotation annotations}
- * @since 2.7.3
- */
- public AnnotationInjectedBeanPostProcessor(Class<? extends Annotation>... annotationTypes) {
- Assert.notEmpty(annotationTypes, "The argument of annotations' types must not empty");
- this.annotationTypes = annotationTypes;
- }
-
- @SafeVarargs
- private static <T> Collection<T> combine(Collection<? extends T>... elements) {
- List<T> allElements = new ArrayList<>();
- for (Collection<? extends T> e : elements) {
- allElements.addAll(e);
- }
- return allElements;
- }
-
- /**
- * Annotation type
- *
- * @return non-null
- * @deprecated 2.7.3, uses {@link #getAnnotationTypes()}
- */
- @Deprecated
- public final Class<? extends Annotation> getAnnotationType() {
- return annotationTypes[0];
- }
-
- protected final Class<? extends Annotation>[] getAnnotationTypes() {
- return annotationTypes;
- }
-
- @Override
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory,
- "AnnotationInjectedBeanPostProcessor requires a ConfigurableListableBeanFactory");
- this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
- }
-
- @Override
- public PropertyValues postProcessPropertyValues(
- PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
-
- InjectionMetadata metadata = findInjectionMetadata(beanName, bean.getClass(), pvs);
- try {
- metadata.inject(bean, beanName, pvs);
- } catch (BeanCreationException ex) {
- throw ex;
- } catch (Throwable ex) {
- throw new BeanCreationException(beanName, "Injection of @" + getAnnotationType().getSimpleName()
- + " dependencies is failed", ex);
- }
- return pvs;
- }
-
-
- /**
- * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated fields
- *
- * @param beanClass The {@link Class} of Bean
- * @return non-null {@link List}
- */
- private List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> findFieldAnnotationMetadata(final Class<?> beanClass) {
-
- final List<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement>();
-
- ReflectionUtils.doWithFields(beanClass, field -> {
-
- for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
-
- AnnotationAttributes attributes = getMergedAttributes(field, annotationType, getEnvironment(), true);
-
- if (attributes != null) {
-
- if (Modifier.isStatic(field.getModifiers())) {
- if (logger.isWarnEnabled()) {
- logger.warn("@" + annotationType.getName() + " is not supported on static fields: " + field);
- }
- return;
- }
-
- elements.add(new AnnotatedFieldElement(field, attributes));
- }
- }
- });
-
- return elements;
-
- }
-
- /**
- * Finds {@link InjectionMetadata.InjectedElement} Metadata from annotated methods
- *
- * @param beanClass The {@link Class} of Bean
- * @return non-null {@link List}
- */
- private List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> findAnnotatedMethodMetadata(final Class<?> beanClass) {
-
- final List<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> elements = new LinkedList<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement>();
-
- ReflectionUtils.doWithMethods(beanClass, method -> {
-
- Method bridgedMethod = findBridgedMethod(method);
-
- if (!isVisibilityBridgeMethodPair(method, bridgedMethod)) {
- return;
- }
-
-
- for (Class<? extends Annotation> annotationType : getAnnotationTypes()) {
-
- AnnotationAttributes attributes = getMergedAttributes(bridgedMethod, annotationType, getEnvironment(), true);
-
- if (attributes != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) {
- if (Modifier.isStatic(method.getModifiers())) {
- if (logger.isWarnEnabled()) {
- logger.warn("@" + annotationType.getName() + " annotation is not supported on static methods: " + method);
- }
- return;
- }
- if (method.getParameterTypes().length == 0) {
- if (logger.isWarnEnabled()) {
- logger.warn("@" + annotationType.getName() + " annotation should only be used on methods with parameters: " +
- method);
- }
- }
- PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, beanClass);
- elements.add(new AnnotatedMethodElement(method, pd, attributes));
- }
- }
- });
-
- return elements;
-
- }
-
-
- private AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata buildAnnotatedMetadata(final Class<?> beanClass) {
- Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = findFieldAnnotationMetadata(beanClass);
- Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = findAnnotatedMethodMetadata(beanClass);
- return new AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata(beanClass, fieldElements, methodElements);
-
- }
-
- private InjectionMetadata findInjectionMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
- // Fall back to class name as cache key, for backwards compatibility with custom callers.
- String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
- // Quick check on the concurrent map first, with minimal locking.
- AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
- if (InjectionMetadata.needsRefresh(metadata, clazz)) {
- synchronized (this.injectionMetadataCache) {
- metadata = this.injectionMetadataCache.get(cacheKey);
- if (InjectionMetadata.needsRefresh(metadata, clazz)) {
- if (metadata != null) {
- metadata.clear(pvs);
- }
- try {
- metadata = buildAnnotatedMetadata(clazz);
- this.injectionMetadataCache.put(cacheKey, metadata);
- } catch (NoClassDefFoundError err) {
- throw new IllegalStateException("Failed to introspect object class [" + clazz.getName() +
- "] for annotation metadata: could not find class that it depends on", err);
- }
- }
- }
- }
- return metadata;
- }
-
- @Override
- public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
- if (beanType != null) {
- InjectionMetadata metadata = findInjectionMetadata(beanName, beanType, null);
- metadata.checkConfigMembers(beanDefinition);
- }
- }
-
- @Override
- public int getOrder() {
- return order;
- }
-
- public void setOrder(int order) {
- this.order = order;
- }
-
- @Override
- public void destroy() throws Exception {
-
- for (Object object : injectedObjectsCache.values()) {
- if (logger.isInfoEnabled()) {
- logger.info(object + " was destroying!");
- }
-
- if (object instanceof DisposableBean) {
- ((DisposableBean) object).destroy();
- }
- }
-
- injectionMetadataCache.clear();
- injectedObjectsCache.clear();
-
- if (logger.isInfoEnabled()) {
- logger.info(getClass() + " was destroying!");
- }
-
- }
-
- @Override
- public void setBeanClassLoader(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- @Override
- public void setEnvironment(Environment environment) {
- this.environment = environment;
- }
-
- protected Environment getEnvironment() {
- return environment;
- }
-
- protected ClassLoader getClassLoader() {
- return classLoader;
- }
-
- protected ConfigurableListableBeanFactory getBeanFactory() {
- return beanFactory;
- }
-
- /**
- * Gets all injected-objects.
- *
- * @return non-null {@link Collection}
- */
- protected Collection<Object> getInjectedObjects() {
- return this.injectedObjectsCache.values();
- }
-
- /**
- * Get injected-object from specified {@link AnnotationAttributes annotation attributes} and Bean Class
- *
- * @param attributes {@link AnnotationAttributes the annotation attributes}
- * @param bean Current bean that will be injected
- * @param beanName Current bean name that will be injected
- * @param injectedType the type of injected-object
- * @param injectedElement {@link InjectionMetadata.InjectedElement}
- * @return An injected object
- * @throws Exception If getting is failed
- */
- protected Object getInjectedObject(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
- InjectionMetadata.InjectedElement injectedElement) throws Exception {
-
- String cacheKey = buildInjectedObjectCacheKey(attributes, bean, beanName, injectedType, injectedElement);
-
- Object injectedObject = injectedObjectsCache.get(cacheKey);
-
- if (injectedObject == null) {
- injectedObject = doGetInjectedBean(attributes, bean, beanName, injectedType, injectedElement);
- // Customized inject-object if necessary
- injectedObjectsCache.putIfAbsent(cacheKey, injectedObject);
- }
-
- return injectedObject;
-
- }
-
- /**
- * Subclass must implement this method to get injected-object. The context objects could help this method if
- * necessary :
- * <ul>
- * <li>{@link #getBeanFactory() BeanFactory}</li>
- * <li>{@link #getClassLoader() ClassLoader}</li>
- * <li>{@link #getEnvironment() Environment}</li>
- * </ul>
- *
- * @param attributes {@link AnnotationAttributes the annotation attributes}
- * @param bean Current bean that will be injected
- * @param beanName Current bean name that will be injected
- * @param injectedType the type of injected-object
- * @param injectedElement {@link InjectionMetadata.InjectedElement}
- * @return The injected object
- * @throws Exception If resolving an injected object is failed.
- */
- protected abstract Object doGetInjectedBean(AnnotationAttributes attributes, Object bean, String beanName, Class<?> injectedType,
- InjectionMetadata.InjectedElement injectedElement) throws Exception;
-
- /**
- * Build a cache key for injected-object. The context objects could help this method if
- * necessary :
- * <ul>
- * <li>{@link #getBeanFactory() BeanFactory}</li>
- * <li>{@link #getClassLoader() ClassLoader}</li>
- * <li>{@link #getEnvironment() Environment}</li>
- * </ul>
- *
- * @param attributes {@link AnnotationAttributes the annotation attributes}
- * @param bean Current bean that will be injected
- * @param beanName Current bean name that will be injected
- * @param injectedType the type of injected-object
- * @param injectedElement {@link InjectionMetadata.InjectedElement}
- * @return Bean cache key
- */
- protected abstract String buildInjectedObjectCacheKey(AnnotationAttributes attributes, Object bean, String beanName,
- Class<?> injectedType,
- InjectionMetadata.InjectedElement injectedElement);
-
- /**
- * Get {@link Map} in injected field.
- *
- * @return non-null ready-only {@link Map}
- */
- protected Map<InjectionMetadata.InjectedElement, Object> getInjectedFieldObjectsMap() {
-
- Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
- new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();
-
- for (AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {
-
- Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements = metadata.getFieldElements();
-
- for (AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement fieldElement : fieldElements) {
-
- injectedElementBeanMap.put(fieldElement, fieldElement.bean);
-
- }
-
- }
-
- return Collections.unmodifiableMap(injectedElementBeanMap);
-
- }
-
- /**
- * Get {@link Map} in injected method.
- *
- * @return non-null {@link Map}
- */
- protected Map<InjectionMetadata.InjectedElement, Object> getInjectedMethodObjectsMap() {
-
- Map<InjectionMetadata.InjectedElement, Object> injectedElementBeanMap =
- new LinkedHashMap<InjectionMetadata.InjectedElement, Object>();
-
- for (AnnotationInjectedBeanPostProcessor.AnnotatedInjectionMetadata metadata : injectionMetadataCache.values()) {
-
- Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements = metadata.getMethodElements();
-
- for (AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement methodElement : methodElements) {
-
- injectedElementBeanMap.put(methodElement, methodElement.object);
-
- }
-
- }
-
- return Collections.unmodifiableMap(injectedElementBeanMap);
-
- }
-
- /**
- * {@link Annotation Annotated} {@link InjectionMetadata} implementation
- */
- private class AnnotatedInjectionMetadata extends InjectionMetadata {
-
- private final Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements;
-
- private final Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements;
-
- public AnnotatedInjectionMetadata(Class<?> targetClass, Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> fieldElements,
- Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> methodElements) {
- super(targetClass, combine(fieldElements, methodElements));
- this.fieldElements = fieldElements;
- this.methodElements = methodElements;
- }
-
- public Collection<AnnotationInjectedBeanPostProcessor.AnnotatedFieldElement> getFieldElements() {
- return fieldElements;
- }
-
- public Collection<AnnotationInjectedBeanPostProcessor.AnnotatedMethodElement> getMethodElements() {
- return methodElements;
- }
- }
-
- /**
- * {@link Annotation Annotated} {@link Method} {@link InjectionMetadata.InjectedElement}
- */
- private class AnnotatedMethodElement extends InjectionMetadata.InjectedElement {
-
- private final Method method;
-
- private final AnnotationAttributes attributes;
-
- private volatile Object object;
-
- protected AnnotatedMethodElement(Method method, PropertyDescriptor pd, AnnotationAttributes attributes) {
- super(method, pd);
- this.method = method;
- this.attributes = attributes;
- }
-
- @Override
- protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
-
- Class<?> injectedType = pd.getPropertyType();
-
- Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
-
- ReflectionUtils.makeAccessible(method);
-
- method.invoke(bean, injectedObject);
-
- }
-
- }
-
- /**
- * {@link Annotation Annotated} {@link Field} {@link InjectionMetadata.InjectedElement}
- */
- public class AnnotatedFieldElement extends InjectionMetadata.InjectedElement {
-
- private final Field field;
-
- private final AnnotationAttributes attributes;
-
- private volatile Object bean;
-
- protected AnnotatedFieldElement(Field field, AnnotationAttributes attributes) {
- super(field, null);
- this.field = field;
- this.attributes = attributes;
- }
-
- @Override
- protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
-
- Class<?> injectedType = field.getType();
-
- Object injectedObject = getInjectedObject(attributes, bean, beanName, injectedType, this);
-
- ReflectionUtils.makeAccessible(field);
-
- field.set(bean, injectedObject);
-
- }
-
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
index 5566c39..80cdfb7 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java
@@ -24,8 +24,7 @@ import org.springframework.core.env.PropertyResolver;
import java.lang.annotation.Annotation;
import java.util.Map;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolvePlaceholders;
+import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
/**
* {@link Annotation} {@link PropertyValues} Adapter
@@ -46,7 +45,7 @@ class AnnotationPropertyValuesAdapter implements PropertyValues {
*/
public AnnotationPropertyValuesAdapter(Map<String, Object> attributes, PropertyResolver propertyResolver,
String... ignoreAttributeNames) {
- this.delegate = new MutablePropertyValues(resolvePlaceholders(attributes, propertyResolver, ignoreAttributeNames));
+ this.delegate = new MutablePropertyValues(getAttributes(attributes, propertyResolver, ignoreAttributeNames));
}
public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver,
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java
index 8293289..28b6a6c 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java
@@ -25,7 +25,7 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
-import static org.apache.dubbo.config.spring.util.BeanRegistrar.hasAlias;
+import static com.alibaba.spring.util.BeanRegistrar.hasAlias;
import static org.springframework.util.ObjectUtils.nullSafeEquals;
import static org.springframework.util.StringUtils.hasText;
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
index 548ffe1..668af04 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
@@ -21,8 +21,8 @@ import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
-import org.apache.dubbo.config.spring.util.AnnotationUtils;
+import com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
@@ -44,9 +44,10 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
+import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
import static java.lang.reflect.Proxy.newProxyInstance;
import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
import static org.springframework.util.StringUtils.hasText;
/**
@@ -55,7 +56,7 @@ import static org.springframework.util.StringUtils.hasText;
*
* @since 2.5.7
*/
-public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor implements
+public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBeanPostProcessor implements
ApplicationContextAware, ApplicationListener {
/**
@@ -299,7 +300,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBean
Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
return buildReferencedBeanName(attributes, injectedType) +
"#source=" + (injectedElement.getMember()) +
- "#attributes=" + AnnotationUtils.resolvePlaceholders(attributes, getEnvironment());
+ "#attributes=" + getAttributes(attributes, getEnvironment());
}
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
index 55cb646..f6aacf4 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceBeanBuilder.java
@@ -34,11 +34,11 @@ import java.beans.PropertyEditorSupport;
import java.util.List;
import java.util.Map;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveServiceInterfaceClass;
-import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getNullableBean;
-import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
+import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
+import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
+import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
+import static com.alibaba.spring.util.ObjectUtils.of;
+import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveServiceInterfaceClass;
import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
@@ -81,7 +81,7 @@ class ReferenceBeanBuilder extends AnnotatedInterfaceConfigBeanBuilder<Reference
String consumerBeanName = getAttribute(attributes, "consumer");
- ConsumerConfig consumerConfig = getNullableBean(applicationContext, consumerBeanName, ConsumerConfig.class);
+ ConsumerConfig consumerConfig = getOptionalBean(applicationContext, consumerBeanName, ConsumerConfig.class);
referenceBean.setConsumer(consumerConfig);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
index ce8b196..c96f7b9 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationBeanPostProcessor.java
@@ -63,9 +63,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static com.alibaba.spring.util.ObjectUtils.of;
import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveServiceInterfaceClass;
-import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
+import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveServiceInterfaceClass;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.context.annotation.AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR;
import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
index 8aef87f..7cd04ec 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java
@@ -25,8 +25,8 @@ import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
-import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveInterfaceName;
+import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
+import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveInterfaceName;
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java
index 6e14d56..7d66b72 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboComponentScanRegistrar.java
@@ -19,7 +19,6 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor;
-import org.apache.dubbo.config.spring.util.BeanRegistrar;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -37,6 +36,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
+import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
/**
@@ -87,7 +87,7 @@ public class DubboComponentScanRegistrar implements ImportBeanDefinitionRegistra
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
// Register @Reference Annotation Bean Processor
- BeanRegistrar.registerInfrastructureBean(registry,
+ registerInfrastructureBean(registry,
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
index 894a363..62f5b69 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingRegistrar.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindin
import org.apache.dubbo.config.spring.beans.factory.config.ConfigurableSourceBeanMetadataElement;
import org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer;
+import com.alibaba.spring.beans.factory.annotation.ConfigurationBeanBindingRegistrar;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -43,12 +44,13 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
+import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
+import static com.alibaba.spring.util.PropertySourcesUtils.normalizePrefix;
import static org.apache.dubbo.config.spring.context.config.NamePropertyDefaultValueDubboConfigBeanCustomizer.BEAN_NAME;
-import static org.apache.dubbo.config.spring.util.BeanRegistrar.registerInfrastructureBean;
-import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.buildPrefix;
-import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getPrefixedProperties;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;
import static org.springframework.beans.factory.support.BeanDefinitionReaderUtils.registerWithGeneratedName;
+import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
/**
* {@link AbstractConfig Dubbo Config} binding Bean registrar
@@ -56,7 +58,9 @@ import static org.springframework.beans.factory.support.BeanDefinitionReaderUtil
* @see EnableDubboConfigBinding
* @see DubboConfigBindingBeanPostProcessor
* @since 2.5.8
+ * @deprecated it will be removed in future, please use {@link ConfigurationBeanBindingRegistrar} for replacement
*/
+@Deprecated
public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware,
ConfigurableSourceBeanMetadataElement {
@@ -67,8 +71,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
- AnnotationAttributes attributes = AnnotationAttributes.fromMap(
- importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBinding.class.getName()));
+ AnnotationAttributes attributes = fromMap(importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBinding.class.getName()));
registerBeanDefinitions(attributes, registry);
@@ -91,7 +94,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
boolean multiple,
BeanDefinitionRegistry registry) {
- Map<String, Object> properties = getPrefixedProperties(environment.getPropertySources(), prefix);
+ Map<String, Object> properties = getSubProperties(environment.getPropertySources(), prefix);
if (CollectionUtils.isEmpty(properties)) {
if (log.isDebugEnabled()) {
@@ -144,7 +147,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
BeanDefinitionBuilder builder = rootBeanDefinition(processorClass);
- String actualPrefix = multiple ? buildPrefix(prefix) + beanName : prefix;
+ String actualPrefix = multiple ? normalizePrefix(prefix) + beanName : prefix;
builder.addConstructorArgValue(actualPrefix).addConstructorArgValue(beanName);
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrar.java
index b420fe1..d1ff887 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigBindingsRegistrar.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.config.AbstractConfig;
+import com.alibaba.spring.beans.factory.annotation.ConfigurationBeanBindingsRegister;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
@@ -33,7 +34,9 @@ import org.springframework.util.Assert;
* @see EnableDubboConfigBindings
* @see DubboConfigBindingRegistrar
* @since 2.5.8
+ * @deprecated it will be removed in future, please use {@link ConfigurationBeanBindingsRegister} for replacement
*/
+@Deprecated
public class DubboConfigBindingsRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware {
private ConfigurableEnvironment environment;
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfiguration.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfiguration.java
index 4f9b5a8..414b827 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfiguration.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfiguration.java
@@ -28,14 +28,17 @@ import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.ConfigCenterBean;
+import com.alibaba.spring.beans.factory.annotation.EnableConfigurationBeanBinding;
+import com.alibaba.spring.beans.factory.annotation.EnableConfigurationBeanBindings;
import org.springframework.context.annotation.Configuration;
/**
* Dubbo {@link AbstractConfig Config} {@link Configuration}
*
+ * @revised 2.7.5
* @see Configuration
- * @see EnableDubboConfigBindings
- * @see EnableDubboConfigBinding
+ * @see EnableConfigurationBeanBindings
+ * @see EnableConfigurationBeanBinding
* @see ApplicationConfig
* @see ModuleConfig
* @see RegistryConfig
@@ -51,17 +54,17 @@ public class DubboConfigConfiguration {
/**
* Single Dubbo {@link AbstractConfig Config} Bean Binding
*/
- @EnableDubboConfigBindings({
- @EnableDubboConfigBinding(prefix = "dubbo.application", type = ApplicationConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.module", type = ModuleConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.registry", type = RegistryConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.monitor", type = MonitorConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.provider", type = ProviderConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.config-center", type = ConfigCenterBean.class),
- @EnableDubboConfigBinding(prefix = "dubbo.metadata-report", type = MetadataReportConfig.class),
- @EnableDubboConfigBinding(prefix = "dubbo.metrics", type = MetricsConfig.class)
+ @EnableConfigurationBeanBindings({
+ @EnableConfigurationBeanBinding(prefix = "dubbo.application", type = ApplicationConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.module", type = ModuleConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.registry", type = RegistryConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.protocol", type = ProtocolConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.monitor", type = MonitorConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.provider", type = ProviderConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.consumer", type = ConsumerConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.config-center", type = ConfigCenterBean.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.metadata-report", type = MetadataReportConfig.class),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.metrics", type = MetricsConfig.class)
})
public static class Single {
@@ -70,17 +73,17 @@ public class DubboConfigConfiguration {
/**
* Multiple Dubbo {@link AbstractConfig Config} Bean Binding
*/
- @EnableDubboConfigBindings({
- @EnableDubboConfigBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.providers", type = ProviderConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.config-centers", type = ConfigCenterBean.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.metadata-reports", type = MetadataReportConfig.class, multiple = true),
- @EnableDubboConfigBinding(prefix = "dubbo.metricses", type = MetricsConfig.class, multiple = true)
+ @EnableConfigurationBeanBindings({
+ @EnableConfigurationBeanBinding(prefix = "dubbo.applications", type = ApplicationConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.modules", type = ModuleConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.registries", type = RegistryConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.protocols", type = ProtocolConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.monitors", type = MonitorConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.providers", type = ProviderConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.config-centers", type = ConfigCenterBean.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.metadata-reports", type = MetadataReportConfig.class, multiple = true),
+ @EnableConfigurationBeanBinding(prefix = "dubbo.metricses", type = MetricsConfig.class, multiple = true)
})
public static class Multiple {
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java
index 18f260a..79db7f4 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboConfigConfigurationRegistrar.java
@@ -25,8 +25,8 @@ import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
-import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
-import static org.apache.dubbo.config.spring.util.BeanRegistrar.registerInfrastructureBean;
+import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
+import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
/**
* Dubbo {@link AbstractConfig Config} {@link ImportBeanDefinitionRegistrar register}, which order can be configured
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java
index 6a23114..c192c8d 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/DubboLifecycleComponentRegistrar.java
@@ -23,7 +23,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
-import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
+import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
/**
* A {@link ImportBeanDefinitionRegistrar register} for the {@link Lifecycle Dubbo Lifecycle} components
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBinding.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBinding.java
index 54fc337..14fabf9 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBinding.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBinding.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.beans.factory.annotation.DubboConfigBindingBeanPostProcessor;
+import com.alibaba.spring.beans.factory.annotation.EnableConfigurationBeanBinding;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.PropertySources;
@@ -44,13 +45,16 @@ import java.lang.annotation.Target;
* @see DubboConfigBindingRegistrar
* @see DubboConfigBindingBeanPostProcessor
* @see EnableDubboConfigBindings
+ * @see EnableConfigurationBeanBinding
* @since 2.5.8
+ * @deprecated it will be removed in future, please use {@link EnableConfigurationBeanBinding} for replacement
*/
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(EnableDubboConfigBindings.class)
@Import(DubboConfigBindingRegistrar.class)
+@Deprecated
public @interface EnableDubboConfigBinding {
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBindings.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBindings.java
index 8c26479..5fde1a4 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBindings.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigBindings.java
@@ -16,6 +16,7 @@
*/
package org.apache.dubbo.config.spring.context.annotation;
+import com.alibaba.spring.beans.factory.annotation.EnableConfigurationBeanBindings;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Annotation;
@@ -28,13 +29,15 @@ import java.lang.annotation.Target;
/**
* Multiple {@link EnableDubboConfigBinding} {@link Annotation}
*
- * @since 2.5.8
* @see EnableDubboConfigBinding
+ * @since 2.5.8
+ * @deprecated it will be removed in future, please use {@link EnableConfigurationBeanBindings} for replacement
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DubboConfigBindingsRegistrar.class)
+@Deprecated
public @interface EnableDubboConfigBindings {
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java
index 2f8c446..cc1753d 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java
@@ -24,7 +24,7 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Arrays;
-import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
+import static com.alibaba.spring.util.ObjectUtils.of;
import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
/**
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
index c989a88..1c87e95 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java
@@ -23,7 +23,7 @@ import org.springframework.validation.DataBinder;
import java.util.Map;
-import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getPrefixedProperties;
+import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
/**
* Default {@link DubboConfigBinder} implementation based on Spring {@link DataBinder}
@@ -37,7 +37,7 @@ public class DefaultDubboConfigBinder extends AbstractDubboConfigBinder {
dataBinder.setIgnoreInvalidFields(isIgnoreInvalidFields());
dataBinder.setIgnoreUnknownFields(isIgnoreUnknownFields());
// Get properties under specified prefix from PropertySources
- Map<String, Object> properties = getPrefixedProperties(getPropertySources(), prefix);
+ Map<String, Object> properties = getSubProperties(getPropertySources(), prefix);
// Convert Map to MutablePropertyValues
MutablePropertyValues propertyValues = new MutablePropertyValues(properties);
// Bind
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionFactory.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionFactory.java
index 1aed3a6..863a677 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionFactory.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/extension/SpringExtensionFactory.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.config.DubboShutdownHook;
-import org.apache.dubbo.config.spring.util.BeanFactoryUtils;
+import org.apache.dubbo.config.spring.util.ApplicationContextUtils;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
@@ -49,7 +49,7 @@ public class SpringExtensionFactory implements ExtensionFactory {
((ConfigurableApplicationContext) context).registerShutdownHook();
DubboShutdownHook.getDubboShutdownHook().unregister();
}
- BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);
+ ApplicationContextUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);
}
public static void removeApplicationContext(ApplicationContext context) {
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java
index 4a8e963..600197f 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/AnnotationBeanDefinitionParser.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.config.spring.schema;
import org.apache.dubbo.config.spring.beans.factory.annotation.ReferenceAnnotationBeanPostProcessor;
import org.apache.dubbo.config.spring.beans.factory.annotation.ServiceAnnotationBeanPostProcessor;
-import org.apache.dubbo.config.spring.util.BeanRegistrar;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
@@ -28,12 +27,12 @@ import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
+import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
import static org.springframework.util.StringUtils.trimArrayElements;
/**
* @link BeanDefinitionParser}
- *
* @see ServiceAnnotationBeanPostProcessor
* @see ReferenceAnnotationBeanPostProcessor
* @since 2.5.9
@@ -79,7 +78,7 @@ public class AnnotationBeanDefinitionParser extends AbstractSingleBeanDefinition
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
// Register @Reference Annotation Bean Processor
- BeanRegistrar.registerInfrastructureBean(registry,
+ registerInfrastructureBean(registry,
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
index 4bbced6..d2a3e08 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java
@@ -53,8 +53,8 @@ import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
+import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
import static org.apache.dubbo.common.constants.CommonConstants.HIDE_KEY_PREFIX;
-import static org.apache.dubbo.config.spring.util.BeanRegistrar.registerInfrastructureBean;
/**
* AbstractBeanDefinitionParser
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
index ae6ea43..3013eaf 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandler.java
@@ -31,8 +31,8 @@ import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
import org.apache.dubbo.config.spring.beans.factory.config.ConfigurableSourceBeanMetadataElement;
import org.apache.dubbo.config.spring.context.DubboLifecycleComponentApplicationListener;
-import org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils;
+import com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
@@ -40,7 +40,7 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.w3c.dom.Element;
-import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
+import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
/**
* DubboNamespaceHandler
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
deleted file mode 100644
index 69cb7d8..0000000
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtils.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.context.annotation.AnnotatedBeanDefinitionReader;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.util.ObjectUtils;
-
-import java.lang.annotation.Annotation;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.Objects;
-import java.util.Set;
-
-import static java.lang.String.format;
-import static java.util.Arrays.asList;
-import static org.springframework.util.ClassUtils.resolveClassName;
-
-/**
- * Annotated {@link BeanDefinition} Utilities
- * <p>
- *
- * @since 2.6.6
- */
-public abstract class AnnotatedBeanDefinitionRegistryUtils {
-
- private static final Log logger = LogFactory.getLog(AnnotatedBeanDefinitionRegistryUtils.class);
-
- /**
- * Is present bean that was registered by the specified {@link Annotation annotated} {@link Class class}
- *
- * @param registry {@link BeanDefinitionRegistry}
- * @param annotatedClass the {@link Annotation annotated} {@link Class class}
- * @return if present, return <code>true</code>, or <code>false</code>
- * @since 2.7.3
- */
- public static boolean isPresentBean(BeanDefinitionRegistry registry, Class<?> annotatedClass) {
-
- boolean present = false;
-
- String[] beanNames = registry.getBeanDefinitionNames();
-
- ClassLoader classLoader = annotatedClass.getClassLoader();
-
- for (String beanName : beanNames) {
- BeanDefinition beanDefinition = registry.getBeanDefinition(beanName);
- if (beanDefinition instanceof AnnotatedBeanDefinition) {
- AnnotationMetadata annotationMetadata = ((AnnotatedBeanDefinition) beanDefinition).getMetadata();
- String className = annotationMetadata.getClassName();
- Class<?> targetClass = resolveClassName(className, classLoader);
- present = Objects.equals(targetClass, annotatedClass);
- if (present) {
- if (logger.isDebugEnabled()) {
- logger.debug(format("The annotatedClass[class : %s , bean name : %s] was present in registry[%s]",
- className, beanName, registry));
- }
- break;
- }
- }
- }
-
- return present;
- }
-
- /**
- * Register Beans if not present in {@link BeanDefinitionRegistry registry}
- *
- * @param registry {@link BeanDefinitionRegistry}
- * @param annotatedClasses {@link Annotation annotation} class
- * @revision 2.7.3 {@link #isPresentBean(BeanDefinitionRegistry, Class)}
- */
- public static void registerBeans(BeanDefinitionRegistry registry, Class<?>... annotatedClasses) {
-
- if (ObjectUtils.isEmpty(annotatedClasses)) {
- return;
- }
-
- Set<Class<?>> classesToRegister = new LinkedHashSet<>(asList(annotatedClasses));
-
- // Remove all annotated-classes that have been registered
- Iterator<Class<?>> iterator = classesToRegister.iterator();
-
- while (iterator.hasNext()) {
- Class<?> annotatedClass = iterator.next();
- if (isPresentBean(registry, annotatedClass)) {
- iterator.remove();
- }
- }
-
- AnnotatedBeanDefinitionReader reader = new AnnotatedBeanDefinitionReader(registry);
-
- if (logger.isDebugEnabled()) {
- logger.debug(registry.getClass().getSimpleName() + " will register annotated classes : " + asList(annotatedClasses) + " .");
- }
-
- reader.register(classesToRegister.toArray(new Class[0]));
-
- // clear
- classesToRegister.clear();
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java
deleted file mode 100644
index 148048f..0000000
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.apache.dubbo.config.annotation.Reference;
-import org.apache.dubbo.config.annotation.Service;
-
-import org.springframework.core.annotation.AnnotationAttributes;
-import org.springframework.core.env.Environment;
-import org.springframework.core.env.PropertyResolver;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.AnnotatedElement;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import static java.lang.String.valueOf;
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.unmodifiableMap;
-import static org.springframework.core.annotation.AnnotatedElementUtils.getMergedAnnotation;
-import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
-import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
-import static org.springframework.core.annotation.AnnotationUtils.getDefaultValue;
-import static org.springframework.util.ClassUtils.getAllInterfacesForClass;
-import static org.springframework.util.ClassUtils.resolveClassName;
-import static org.springframework.util.CollectionUtils.isEmpty;
-import static org.springframework.util.ObjectUtils.containsElement;
-import static org.springframework.util.ObjectUtils.nullSafeEquals;
-import static org.springframework.util.StringUtils.hasText;
-import static org.springframework.util.StringUtils.trimWhitespace;
-
-/**
- * Annotation Utilities Class
- *
- * @see org.springframework.core.annotation.AnnotationUtils
- * @since 2.5.11
- */
-public class AnnotationUtils {
-
-
- @Deprecated
- public static String resolveInterfaceName(Service service, Class<?> defaultInterfaceClass)
- throws IllegalStateException {
-
- String interfaceName;
- if (hasText(service.interfaceName())) {
- interfaceName = service.interfaceName();
- } else if (!void.class.equals(service.interfaceClass())) {
- interfaceName = service.interfaceClass().getName();
- } else if (defaultInterfaceClass.isInterface()) {
- interfaceName = defaultInterfaceClass.getName();
- } else {
- throw new IllegalStateException(
- "The @Service undefined interfaceClass or interfaceName, and the type "
- + defaultInterfaceClass.getName() + " is not a interface.");
- }
-
- return interfaceName;
-
- }
-
- /**
- * Resolve the interface name from {@link AnnotationAttributes}
- *
- * @param attributes {@link AnnotationAttributes} instance, may be {@link Service @Service} or {@link Reference @Reference}
- * @param defaultInterfaceClass the default {@link Class class} of interface
- * @return the interface name if found
- * @throws IllegalStateException if interface name was not found
- */
- public static String resolveInterfaceName(AnnotationAttributes attributes, Class<?> defaultInterfaceClass) {
- Boolean generic = getAttribute(attributes, "generic");
- if (generic != null && generic) {
- // it's a generic reference
- String interfaceClassName = getAttribute(attributes, "interfaceName");
- Assert.hasText(interfaceClassName,
- "@Reference interfaceName() must be present when reference a generic service!");
- return interfaceClassName;
- }
- return resolveServiceInterfaceClass(attributes, defaultInterfaceClass).getName();
- }
-
- /**
- * Get the attribute value
- *
- * @param attributes {@link AnnotationAttributes the annotation attributes}
- * @param name the name of attribute
- * @param <T> the type of attribute value
- * @return the attribute value if found
- * @since 2.7.3
- */
- public static <T> T getAttribute(AnnotationAttributes attributes, String name) {
- return (T) attributes.get(name);
- }
-
- /**
- * Resolve the {@link Class class} of Dubbo Service interface from the specified
- * {@link AnnotationAttributes annotation attributes} and annotated {@link Class class}.
- *
- * @param attributes {@link AnnotationAttributes annotation attributes}
- * @param defaultInterfaceClass the annotated {@link Class class}.
- * @return the {@link Class class} of Dubbo Service interface
- * @throws IllegalArgumentException if can't resolved
- */
- public static Class<?> resolveServiceInterfaceClass(AnnotationAttributes attributes, Class<?> defaultInterfaceClass)
- throws IllegalArgumentException {
-
- ClassLoader classLoader = defaultInterfaceClass != null ? defaultInterfaceClass.getClassLoader() : Thread.currentThread().getContextClassLoader();
-
- Class<?> interfaceClass = getAttribute(attributes, "interfaceClass");
-
- if (void.class.equals(interfaceClass)) { // default or set void.class for purpose.
-
- interfaceClass = null;
-
- String interfaceClassName = getAttribute(attributes, "interfaceName");
-
- if (hasText(interfaceClassName)) {
- if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
- interfaceClass = resolveClassName(interfaceClassName, classLoader);
- }
- }
-
- }
-
- if (interfaceClass == null && defaultInterfaceClass != null) {
- // Find all interfaces from the annotated class
- // To resolve an issue : https://github.com/apache/dubbo/issues/3251
- Class<?>[] allInterfaces = getAllInterfacesForClass(defaultInterfaceClass);
-
- if (allInterfaces.length > 0) {
- interfaceClass = allInterfaces[0];
- }
-
- }
-
- Assert.notNull(interfaceClass,
- "@Service interfaceClass() or interfaceName() or interface class must be present!");
-
- Assert.isTrue(interfaceClass.isInterface(),
- "The annotated type must be an interface!");
-
- return interfaceClass;
- }
-
- @Deprecated
- public static String resolveInterfaceName(Reference reference, Class<?> defaultInterfaceClass)
- throws IllegalStateException {
-
- String interfaceName;
- if (!"".equals(reference.interfaceName())) {
- interfaceName = reference.interfaceName();
- } else if (!void.class.equals(reference.interfaceClass())) {
- interfaceName = reference.interfaceClass().getName();
- } else if (defaultInterfaceClass.isInterface()) {
- interfaceName = defaultInterfaceClass.getName();
- } else {
- throw new IllegalStateException(
- "The @Reference undefined interfaceClass or interfaceName, and the type "
- + defaultInterfaceClass.getName() + " is not a interface.");
- }
-
- return interfaceName;
-
- }
-
- /**
- * Get the {@link Annotation} attributes
- *
- * @param annotation specified {@link Annotation}
- * @param ignoreDefaultValue whether ignore default value or not
- * @param ignoreAttributeNames the attribute names of annotation should be ignored
- * @return non-null
- * @since 2.6.6
- * @deprecated
- */
- @Deprecated
- public static Map<String, Object> getAttributes(Annotation annotation, boolean ignoreDefaultValue,
- String... ignoreAttributeNames) {
- return getAttributes(annotation, null, ignoreDefaultValue, ignoreAttributeNames);
- }
-
- /**
- * Get the {@link Annotation} attributes
- *
- * @param annotation specified {@link Annotation}
- * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
- * @param ignoreDefaultValue whether ignore default value or not
- * @param ignoreAttributeNames the attribute names of annotation should be ignored
- * @return non-null
- * @since 2.6.6
- */
- public static Map<String, Object> getAttributes(Annotation annotation, PropertyResolver propertyResolver,
- boolean ignoreDefaultValue, String... ignoreAttributeNames) {
-
- if (annotation == null) {
- return emptyMap();
- }
-
- Map<String, Object> attributes = getAnnotationAttributes(annotation);
-
- Map<String, Object> actualAttributes = new LinkedHashMap<>();
-
- for (Map.Entry<String, Object> entry : attributes.entrySet()) {
-
- String attributeName = entry.getKey();
- Object attributeValue = entry.getValue();
-
- // ignore default attribute value
- if (ignoreDefaultValue && nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) {
- continue;
- }
- actualAttributes.put(attributeName, attributeValue);
- }
-
- return resolvePlaceholders(actualAttributes, propertyResolver, ignoreAttributeNames);
- }
-
- /**
- * Resolve the placeholders from the specified annotation attributes
- *
- * @param sourceAnnotationAttributes the source of annotation attributes
- * @param propertyResolver {@link PropertyResolver}
- * @param ignoreAttributeNames the attribute names to be ignored
- * @return a new resolved annotation attributes , non-null and read-only
- * @since 2.7.3
- */
- public static Map<String, Object> resolvePlaceholders(Map<String, Object> sourceAnnotationAttributes,
- PropertyResolver propertyResolver,
- String... ignoreAttributeNames) {
-
- if (isEmpty(sourceAnnotationAttributes)) {
- return emptyMap();
- }
-
- Map<String, Object> resolvedAnnotationAttributes = new LinkedHashMap<>();
-
- for (Map.Entry<String, Object> entry : sourceAnnotationAttributes.entrySet()) {
-
- String attributeName = entry.getKey();
-
- // ignore attribute name to skip
- if (containsElement(ignoreAttributeNames, attributeName)) {
- continue;
- }
-
- Object attributeValue = entry.getValue();
-
- if (attributeValue instanceof String) {
- attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver);
- } else if (attributeValue instanceof String[]) {
- String[] values = (String[]) attributeValue;
- for (int i = 0; i < values.length; i++) {
- values[i] = resolvePlaceholders(values[i], propertyResolver);
- }
- attributeValue = values;
- }
-
- resolvedAnnotationAttributes.put(attributeName, attributeValue);
- }
-
- return unmodifiableMap(resolvedAnnotationAttributes);
- }
-
- /**
- * Get {@link AnnotationAttributes the annotation attributes} after merging and resolving the placeholders
- *
- * @param annotatedElement {@link AnnotatedElement the annotated element}
- * @param annotationType the {@link Class tyoe} pf {@link Annotation annotation}
- * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment}
- * @param ignoreDefaultValue whether ignore default value or not
- * @param ignoreAttributeNames the attribute names of annotation should be ignored
- * @return If the specified annotation type is not found, return <code>null</code>
- * @since 2.7.3
- */
- public static AnnotationAttributes getMergedAttributes(AnnotatedElement annotatedElement,
- Class<? extends Annotation> annotationType,
- PropertyResolver propertyResolver,
- boolean ignoreDefaultValue,
- String... ignoreAttributeNames) {
- Annotation annotation = getMergedAnnotation(annotatedElement, annotationType);
- return annotation == null ? null : fromMap(getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames));
-
- }
-
- private static String resolvePlaceholders(String attributeValue, PropertyResolver propertyResolver) {
- String resolvedValue = attributeValue;
- if (propertyResolver != null) {
- resolvedValue = propertyResolver.resolvePlaceholders(resolvedValue);
- resolvedValue = trimWhitespace(resolvedValue);
- }
- return resolvedValue;
- }
-
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ApplicationContextUtils.java
similarity index 57%
rename from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java
rename to dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ApplicationContextUtils.java
index 76f7379..72d1e1c 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanFactoryUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ApplicationContextUtils.java
@@ -17,19 +17,12 @@
package org.apache.dubbo.config.spring.util;
import org.springframework.beans.factory.BeanFactory;
-import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.support.AbstractApplicationContext;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-import static java.util.Collections.emptyList;
-import static org.springframework.util.ObjectUtils.isEmpty;
/**
* {@link BeanFactory} Utilities class
@@ -39,7 +32,7 @@ import static org.springframework.util.ObjectUtils.isEmpty;
* @see org.springframework.beans.factory.BeanFactoryUtils
* @since 2.5.7
*/
-public class BeanFactoryUtils {
+public class ApplicationContextUtils {
public static boolean addApplicationListener(ApplicationContext applicationContext, ApplicationListener listener) {
try {
@@ -64,51 +57,4 @@ public class BeanFactoryUtils {
}
return false;
}
-
- /**
- * Get nullable Bean
- *
- * @param beanFactory {@link ListableBeanFactory}
- * @param beanName the name of Bean
- * @param beanType the {@link Class type} of Bean
- * @param <T> the {@link Class type} of Bean
- * @return A bean if present , or <code>null</code>
- */
- public static <T> T getNullableBean(ListableBeanFactory beanFactory, String beanName, Class<T> beanType) {
- T bean = null;
- try {
- bean = beanFactory.getBean(beanName, beanType);
- } catch (Throwable ignored) {
- // Any exception will be ignored to handle
- }
- return bean;
- }
-
-
- /**
- * Gets name-matched Beans from {@link ListableBeanFactory BeanFactory}
- *
- * @param beanFactory {@link ListableBeanFactory BeanFactory}
- * @param beanNames the names of Bean
- * @param beanType the {@link Class type} of Bean
- * @param <T> the {@link Class type} of Bean
- * @return the read-only and non-null {@link List} of Bean names
- */
- public static <T> List<T> getBeans(ListableBeanFactory beanFactory, String[] beanNames, Class<T> beanType) {
-
- if (isEmpty(beanNames)) {
- return emptyList();
- }
-
- List<T> beans = new ArrayList<T>(beanNames.length);
-
- for (String beanName : beanNames) {
- T bean = getNullableBean(beanFactory, beanName, beanType);
- if (bean != null) {
- beans.add(bean);
- }
- }
-
- return Collections.unmodifiableList(beans);
- }
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java
deleted file mode 100644
index 04dd601..0000000
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionRegistry;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.core.AliasRegistry;
-
-import static org.springframework.util.ObjectUtils.containsElement;
-import static org.springframework.util.StringUtils.hasText;
-
-/**
- * Bean Registrar
- *
- * @since 2.5.7
- */
-public class BeanRegistrar {
-
- /**
- * Register Infrastructure Bean
- *
- * @param beanDefinitionRegistry {@link BeanDefinitionRegistry}
- * @param beanType the type of bean
- * @param beanName the name of bean
- */
- public static void registerInfrastructureBean(BeanDefinitionRegistry beanDefinitionRegistry,
- String beanName,
- Class<?> beanType) {
-
- if (!beanDefinitionRegistry.containsBeanDefinition(beanName)) {
- RootBeanDefinition beanDefinition = new RootBeanDefinition(beanType);
- beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- beanDefinitionRegistry.registerBeanDefinition(beanName, beanDefinition);
- }
-
- }
-
- /**
- * Detect the alias is present or not in the given bean name from {@link AliasRegistry}
- *
- * @param registry {@link AliasRegistry}
- * @param beanName the bean name
- * @param alias alias to test
- * @return if present, return <code>true</code>, or <code>false</code>
- */
- public static boolean hasAlias(AliasRegistry registry, String beanName, String alias) {
- return hasText(beanName) && hasText(alias) && containsElement(registry.getAliases(beanName), alias);
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java
new file mode 100644
index 0000000..7cf3527
--- /dev/null
+++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java
@@ -0,0 +1,150 @@
+/*
+ * 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 org.apache.dubbo.config.spring.util;
+
+import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.annotation.Service;
+
+import org.springframework.core.annotation.AnnotationAttributes;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+
+import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
+import static org.springframework.util.ClassUtils.getAllInterfacesForClass;
+import static org.springframework.util.ClassUtils.resolveClassName;
+import static org.springframework.util.StringUtils.hasText;
+
+/**
+ * Dubbbo Annotation Utilities Class
+ *
+ * @see org.springframework.core.annotation.AnnotationUtils
+ * @since 2.5.11
+ */
+public class DubboAnnotationUtils {
+
+
+ @Deprecated
+ public static String resolveInterfaceName(Service service, Class<?> defaultInterfaceClass)
+ throws IllegalStateException {
+
+ String interfaceName;
+ if (hasText(service.interfaceName())) {
+ interfaceName = service.interfaceName();
+ } else if (!void.class.equals(service.interfaceClass())) {
+ interfaceName = service.interfaceClass().getName();
+ } else if (defaultInterfaceClass.isInterface()) {
+ interfaceName = defaultInterfaceClass.getName();
+ } else {
+ throw new IllegalStateException(
+ "The @Service undefined interfaceClass or interfaceName, and the type "
+ + defaultInterfaceClass.getName() + " is not a interface.");
+ }
+
+ return interfaceName;
+
+ }
+
+ /**
+ * Resolve the interface name from {@link AnnotationAttributes}
+ *
+ * @param attributes {@link AnnotationAttributes} instance, may be {@link Service @Service} or {@link Reference @Reference}
+ * @param defaultInterfaceClass the default {@link Class class} of interface
+ * @return the interface name if found
+ * @throws IllegalStateException if interface name was not found
+ */
+ public static String resolveInterfaceName(AnnotationAttributes attributes, Class<?> defaultInterfaceClass) {
+ Boolean generic = getAttribute(attributes, "generic");
+ if (generic != null && generic) {
+ // it's a generic reference
+ String interfaceClassName = getAttribute(attributes, "interfaceName");
+ Assert.hasText(interfaceClassName,
+ "@Reference interfaceName() must be present when reference a generic service!");
+ return interfaceClassName;
+ }
+ return resolveServiceInterfaceClass(attributes, defaultInterfaceClass).getName();
+ }
+
+ /**
+ * Resolve the {@link Class class} of Dubbo Service interface from the specified
+ * {@link AnnotationAttributes annotation attributes} and annotated {@link Class class}.
+ *
+ * @param attributes {@link AnnotationAttributes annotation attributes}
+ * @param defaultInterfaceClass the annotated {@link Class class}.
+ * @return the {@link Class class} of Dubbo Service interface
+ * @throws IllegalArgumentException if can't resolved
+ */
+ public static Class<?> resolveServiceInterfaceClass(AnnotationAttributes attributes, Class<?> defaultInterfaceClass)
+ throws IllegalArgumentException {
+
+ ClassLoader classLoader = defaultInterfaceClass != null ? defaultInterfaceClass.getClassLoader() : Thread.currentThread().getContextClassLoader();
+
+ Class<?> interfaceClass = getAttribute(attributes, "interfaceClass");
+
+ if (void.class.equals(interfaceClass)) { // default or set void.class for purpose.
+
+ interfaceClass = null;
+
+ String interfaceClassName = getAttribute(attributes, "interfaceName");
+
+ if (hasText(interfaceClassName)) {
+ if (ClassUtils.isPresent(interfaceClassName, classLoader)) {
+ interfaceClass = resolveClassName(interfaceClassName, classLoader);
+ }
+ }
+
+ }
+
+ if (interfaceClass == null && defaultInterfaceClass != null) {
+ // Find all interfaces from the annotated class
+ // To resolve an issue : https://github.com/apache/dubbo/issues/3251
+ Class<?>[] allInterfaces = getAllInterfacesForClass(defaultInterfaceClass);
+
+ if (allInterfaces.length > 0) {
+ interfaceClass = allInterfaces[0];
+ }
+
+ }
+
+ Assert.notNull(interfaceClass,
+ "@Service interfaceClass() or interfaceName() or interface class must be present!");
+
+ Assert.isTrue(interfaceClass.isInterface(),
+ "The annotated type must be an interface!");
+
+ return interfaceClass;
+ }
+
+ @Deprecated
+ public static String resolveInterfaceName(Reference reference, Class<?> defaultInterfaceClass)
+ throws IllegalStateException {
+
+ String interfaceName;
+ if (!"".equals(reference.interfaceName())) {
+ interfaceName = reference.interfaceName();
+ } else if (!void.class.equals(reference.interfaceClass())) {
+ interfaceName = reference.interfaceClass().getName();
+ } else if (defaultInterfaceClass.isInterface()) {
+ interfaceName = defaultInterfaceClass.getName();
+ } else {
+ throw new IllegalStateException(
+ "The @Reference undefined interfaceClass or interfaceName, and the type "
+ + defaultInterfaceClass.getName() + " is not a interface.");
+ }
+
+ return interfaceName;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java
deleted file mode 100644
index 007f17f..0000000
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.springframework.core.env.EnumerablePropertySource;
-import org.springframework.core.env.MutablePropertySources;
-import org.springframework.core.env.PropertyResolver;
-import org.springframework.core.env.PropertySource;
-import org.springframework.core.env.PropertySources;
-import org.springframework.core.env.PropertySourcesPropertyResolver;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Properties;
-
-import static java.util.Collections.unmodifiableMap;
-
-
-/**
- * {@link PropertySources} Utilities
- * <p>
- *
- * @since 2.6.6
- */
-public abstract class PropertySourcesUtils {
-
- /**
- * Get prefixed {@link Properties}
- *
- * @param propertySources {@link PropertySource} Iterable
- * @param prefix the prefix of property name
- * @return Map
- * @see Properties
- */
- public static Map<String, Object> getPrefixedProperties(Iterable<PropertySource<?>> propertySources, String prefix) {
-
- MutablePropertySources mutablePropertySources = new MutablePropertySources();
-
- for (PropertySource<?> source : propertySources) {
- mutablePropertySources.addLast(source);
- }
-
- return getPrefixedProperties(mutablePropertySources, prefix);
-
- }
-
- /**
- * Get prefixed {@link Properties}
- *
- * @param propertySources {@link PropertySources}
- * @param prefix the prefix of property name
- * @return Map
- * @see Properties
- */
- public static Map<String, Object> getPrefixedProperties(PropertySources propertySources, String prefix) {
-
- PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources);
-
- Map<String, Object> prefixedProperties = new LinkedHashMap<>();
-
- String normalizedPrefix = buildPrefix(prefix);
-
- Iterator<PropertySource<?>> iterator = propertySources.iterator();
-
- while (iterator.hasNext()) {
- PropertySource<?> source = iterator.next();
- if (source instanceof EnumerablePropertySource) {
- for (String name : ((EnumerablePropertySource<?>) source).getPropertyNames()) {
- if (!prefixedProperties.containsKey(name) && name.startsWith(normalizedPrefix)) {
- String subName = name.substring(normalizedPrefix.length());
- if (!prefixedProperties.containsKey(subName)) { // take first one
- Object value = source.getProperty(name);
- if (value instanceof String) {
- // Resolve placeholder
- value = propertyResolver.resolvePlaceholders((String) value);
- }
- prefixedProperties.put(subName, value);
- }
- }
- }
- }
- }
-
- return unmodifiableMap(prefixedProperties);
- }
-
- /**
- * Build the prefix
- *
- * @param prefix the prefix
- * @return the prefix
- */
- public static String buildPrefix(String prefix) {
- if (prefix.endsWith(".")) {
- return prefix;
- } else {
- return prefix + ".";
- }
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
index 83ec889..efc18ea 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessorTest.java
@@ -97,17 +97,19 @@ public class ReferenceAnnotationBeanPostProcessorTest {
TestBean testBean = context.getBean(TestBean.class);
DemoService demoService = testBean.getDemoService();
+ Map<String, DemoService> demoServicesMap = context.getBeansOfType(DemoService.class);
+
+ Assert.assertNotNull(testBean.getDemoServiceFromAncestor());
+ Assert.assertNotNull(testBean.getDemoServiceFromParent());
+ Assert.assertNotNull(testBean.getDemoService());
+ Assert.assertNotNull(testBean.autowiredDemoService);
+ Assert.assertEquals(1, demoServicesMap.size());
Assert.assertEquals("Hello,Mercy", demoService.sayName("Mercy"));
Assert.assertEquals("Greeting, Mercy", defaultHelloService.sayHello("Mercy"));
Assert.assertEquals("Hello, Mercy", helloServiceImpl.sayHello("Mercy"));
-
Assert.assertEquals("Greeting, Mercy", helloService.sayHello("Mercy"));
- Assert.assertNotNull(testBean.getDemoServiceFromAncestor());
- Assert.assertNotNull(testBean.getDemoServiceFromParent());
- Assert.assertNotNull(testBean.getDemoService());
- Assert.assertNotNull(testBean.autowiredDemoService);
Assert.assertEquals("Hello,Mercy", testBean.getDemoServiceFromAncestor().sayName("Mercy"));
Assert.assertEquals("Hello,Mercy", testBean.getDemoServiceFromParent().sayName("Mercy"));
@@ -118,9 +120,6 @@ public class ReferenceAnnotationBeanPostProcessorTest {
Assert.assertEquals("Hello,Mercy", myDemoService.sayName("Mercy"));
- Map<String, DemoService> demoServicesMap = context.getBeansOfType(DemoService.class);
-
- Assert.assertEquals(1, demoServicesMap.size());
for (DemoService demoService1 : demoServicesMap.values()) {
@@ -165,7 +164,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
InjectionMetadata.InjectedElement injectedElement = entry.getKey();
- Assert.assertEquals("org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedFieldElement",
+ Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor$AnnotatedFieldElement",
injectedElement.getClass().getName());
}
@@ -187,7 +186,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
InjectionMetadata.InjectedElement injectedElement = entry.getKey();
- Assert.assertEquals("org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedMethodElement",
+ Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor$AnnotatedMethodElement",
injectedElement.getClass().getName());
}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
index 3086600..3aabd80 100644
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/context/annotation/EnableDubboConfigTest.java
@@ -32,10 +32,11 @@ import org.springframework.context.annotation.PropertySource;
import java.util.Map;
-import static org.apache.dubbo.config.spring.util.BeanRegistrar.hasAlias;
+import static com.alibaba.spring.util.BeanRegistrar.hasAlias;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
+
/**
* {@link EnableDubboConfig} Test
*
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java
deleted file mode 100644
index 847cee0..0000000
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/AnnotatedBeanDefinitionRegistryUtilsTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.junit.Assert;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.stereotype.Service;
-
-import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.isPresentBean;
-import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-/**
- * {@link AnnotatedBeanDefinitionRegistryUtils} Test
- *
- * @since 2.7.3
- */
-public class AnnotatedBeanDefinitionRegistryUtilsTest {
-
- private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
-
- @BeforeEach
- public void init() {
- context.setAllowBeanDefinitionOverriding(false);
- }
-
- @AfterEach
- public void destroy() {
- context.close();
- }
-
- @Test
- public void testIsPresentBean() {
-
- assertFalse(isPresentBean(context, A.class));
-
- context.register(A.class);
-
- for (int i = 0; i < 9; i++) {
- assertTrue(isPresentBean(context, A.class));
- }
-
- }
-
- @Test
- public void testRegisterBeans() {
-
- registerBeans(context, A.class, A.class);
-
- registerBeans(context, A.class);
-
-
- context.refresh();
-
- A a = context.getBean(A.class);
-
- Assert.assertNotNull(a);
- }
-
-
- @Service
- static class A {
-
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/ApplicationContextUtilsTest.java
similarity index 53%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/ApplicationContextUtilsTest.java
index 57832cc..b7ebb00 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/ApplicationContextUtilsTest.java
@@ -16,22 +16,31 @@
*/
package org.apache.dubbo.config.spring.util;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+
+import static org.apache.dubbo.config.spring.util.ApplicationContextUtils.addApplicationListener;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
/**
- * Object Utilities
+ * {@link ApplicationContextUtils} Test
*
- * @since 2.6.6
+ * @since 2.5.7
*/
-public abstract class ObjectUtils {
+public class ApplicationContextUtilsTest {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
+ private ApplicationContext applicationContext;
+
+ @BeforeEach
+ public void init() {
+ applicationContext = new GenericApplicationContext();
}
+ @Test
+ public void testAddApplicationListener() {
+ assertTrue(addApplicationListener(applicationContext, event -> {
+ }));
+ }
}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/BeanFactoryUtilsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/BeanFactoryUtilsTest.java
deleted file mode 100644
index f265f28..0000000
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/BeanFactoryUtilsTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-
-/**
- * {@link BeanFactoryUtils} Test
- *
- * @since 2.5.7
- */
-public class BeanFactoryUtilsTest {
-
- private AnnotationConfigApplicationContext applicationContext;
-
- @BeforeEach
- public void init() {
- applicationContext = new AnnotationConfigApplicationContext();
- }
-
- @Test
- public void testGetNullableBean() {
-
- applicationContext.register(TestBean.class);
-
- applicationContext.refresh();
-
- TestBean testBean = BeanFactoryUtils.getNullableBean(applicationContext, "testBean", TestBean.class);
-
- Assertions.assertNotNull(testBean);
-
- Assertions.assertEquals("Hello,World", testBean.getName());
-
- }
-
- @Test
- public void testGetNullableBeanIfAbsent() {
-
- applicationContext.refresh();
-
- TestBean testBean = BeanFactoryUtils.getNullableBean(applicationContext, "testBean", TestBean.class);
-
- Assertions.assertNull(testBean);
- }
-
- @Test
- public void testGetBeans() {
-
- applicationContext.register(TestBean.class, TestBean2.class);
-
- applicationContext.refresh();
-
- List<TestBean> testBeans = BeanFactoryUtils.getBeans(applicationContext, new String[]{"testBean"}, TestBean.class);
-
- Assertions.assertEquals(1, testBeans.size());
-
- Assertions.assertEquals("Hello,World", testBeans.get(0).getName());
-
- }
-
- @Test
- public void testGetBeansIfAbsent() {
-
- applicationContext.refresh();
-
- List<TestBean> testBeans = BeanFactoryUtils.getBeans(applicationContext, new String[]{"testBean"}, TestBean.class);
-
- Assertions.assertTrue(testBeans.isEmpty());
-
- }
-
-
- @Component("testBean2")
- private static class TestBean2 extends TestBean {
-
- }
-
- @Component("testBean")
- private static class TestBean {
-
- private String name = "Hello,World";
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
- }
-}
diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/PropertySourcesUtilsTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/PropertySourcesUtilsTest.java
deleted file mode 100644
index 01ce07d..0000000
--- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/util/PropertySourcesUtilsTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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 org.apache.dubbo.config.spring.util;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-import org.springframework.core.env.MapPropertySource;
-import org.springframework.core.env.MutablePropertySources;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * {@link PropertySourcesUtils} Test
- *
- * @see PropertySourcesUtils
- * @since 2.5.8
- */
-public class PropertySourcesUtilsTest {
-
- @Test
- public void testGetPrefixedProperties() {
-
- MutablePropertySources propertySources = new MutablePropertySources();
-
- Map<String, Object> source = new HashMap<String, Object>();
- Map<String, Object> source2 = new HashMap<String, Object>();
-
- MapPropertySource propertySource = new MapPropertySource("propertySource", source);
- MapPropertySource propertySource2 = new MapPropertySource("propertySource2", source2);
-
- propertySources.addLast(propertySource);
- propertySources.addLast(propertySource2);
-
- Map<String, Object> result = PropertySourcesUtils.getPrefixedProperties(propertySources, "user");
-
- Assertions.assertEquals(Collections.emptyMap(), result);
-
- source.put("age", "31");
- source.put("user.name", "Mercy");
- source.put("user.age", "${age}");
-
- source2.put("user.name", "mercyblitz");
- source2.put("user.age", "32");
-
- Map<String, Object> expected = new HashMap<String, Object>();
- expected.put("name", "Mercy");
- expected.put("age", "31");
-
- result = PropertySourcesUtils.getPrefixedProperties(propertySources, "user");
- Assertions.assertEquals(expected, result);
-
- result = PropertySourcesUtils.getPrefixedProperties(propertySources, "");
-
- Assertions.assertEquals(Collections.emptyMap(), result);
-
- result = PropertySourcesUtils.getPrefixedProperties(propertySources, "no-exists");
-
- Assertions.assertEquals(Collections.emptyMap(), result);
-
- }
-
-}
\ No newline at end of file
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 76168b7..f0658ea 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -144,6 +144,9 @@
<!-- Eureka -->
<eureka.version>1.9.12</eureka.version>
+ <!-- Alibaba -->
+ <alibaba_spring_context_support_version>1.0.4-SNAPSHOT</alibaba_spring_context_support_version>
+
<jaxb_version>2.2.7</jaxb_version>
<activation_version>1.2.0</activation_version>
<test_container_version>1.11.2</test_container_version>
@@ -277,6 +280,14 @@
<artifactId>eureka-core</artifactId>
<version>${eureka.version}</version>
</dependency>
+
+ <!-- Alibaba -->
+ <dependency>
+ <groupId>com.alibaba.spring</groupId>
+ <artifactId>spring-context-support</artifactId>
+ <version>${alibaba_spring_context_support_version}</version>
+ </dependency>
+
<dependency>
<groupId>com.googlecode.xmemcached</groupId>
<artifactId>xmemcached</artifactId>
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java
index 65981f5..85f189b 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMapping.java
@@ -27,11 +27,12 @@ import java.util.List;
import java.util.Set;
import static java.util.Arrays.asList;
-import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.DEFAULT_MAPPING_GROUP;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;
/**
* The {@link ServiceNameMapping} implementation based on {@link DynamicConfiguration}
+ *
+ * @since 2.7.5
*/
public class DynamicConfigurationServiceNameMapping implements ServiceNameMapping {
@@ -54,13 +55,14 @@ public class DynamicConfigurationServiceNameMapping implements ServiceNameMappin
// the Dubbo Service Key as group
// the service(application) name as key
- // It does matter whatever the content is, we just need a record
- String app = ApplicationModel.getApplication();
+ // It does not matter whatever the content is, we just need a record
+ String key = ApplicationModel.getApplication();
+ String content = String.valueOf(System.currentTimeMillis());
execute(() -> {
- dynamicConfiguration.publishConfig(buildKey(serviceInterface, group, version, protocol), app);
+ dynamicConfiguration.publishConfig(key, buildGroup(serviceInterface, group, version, protocol), content);
if (logger.isInfoEnabled()) {
- logger.info(String.format("Dubbo service[%s] mapped to interface name[%s].",
- app, serviceInterface, app));
+ logger.info(String.format("The Dubbo service key[%s] mapped to service name[%s] with content : %s",
+ key, group, content));
}
});
}
@@ -70,15 +72,17 @@ public class DynamicConfigurationServiceNameMapping implements ServiceNameMappin
DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
+ String key = ApplicationModel.getApplication();
+
Set<String> serviceNames = new LinkedHashSet<>();
execute(() -> {
- Set<String> keys = dynamicConfiguration.getConfigKeys(DEFAULT_MAPPING_GROUP, buildKey(serviceInterface, group, version, protocol));
+ Set<String> keys = dynamicConfiguration.getConfigKeys(buildGroup(serviceInterface, group, version, protocol), key);
serviceNames.addAll(keys);
});
return Collections.unmodifiableSet(serviceNames);
}
- protected static String buildKey(String serviceInterface, String group, String version, String protocol) {
+ protected static String buildGroup(String serviceInterface, String group, String version, String protocol) {
// the issue : https://github.com/apache/dubbo/issues/4671
// StringBuilder groupBuilder = new StringBuilder(serviceInterface)
// .append(KEY_SEPARATOR).append(defaultString(group))
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java
new file mode 100644
index 0000000..830840d
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java
@@ -0,0 +1,225 @@
+/*
+ * 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 org.apache.dubbo.metadata.rest;
+
+
+import org.apache.dubbo.common.utils.CollectionUtils;
+
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+import static java.util.Collections.unmodifiableMap;
+import static org.apache.dubbo.common.utils.StringUtils.isBlank;
+import static org.apache.dubbo.metadata.util.HttpUtils.normalizePath;
+
+/**
+ * The metadata class for REST request
+ *
+ * @since 2.7.5
+ */
+public class RequestMetadata implements Serializable {
+
+ private static final long serialVersionUID = -240099840085329958L;
+
+ private String method;
+
+ private String path;
+
+ private Map<String, List<String>> params = new LinkedHashMap<>();
+
+ private Map<String, List<String>> headers = new LinkedHashMap<>();
+
+ private Set<String> consumes = new LinkedHashSet<>();
+
+ private Set<String> produces = new LinkedHashSet<>();
+
+ /**
+ * Default Constructor
+ */
+ public RequestMetadata() {
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public void setMethod(String method) {
+ this.method = method == null ? null : method.toUpperCase();
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = normalizePath(path);
+ }
+
+ public Map<String, List<String>> getParams() {
+ return unmodifiableMap(params);
+ }
+
+ public void setParams(Map<String, List<String>> params) {
+ params(params);
+ }
+
+ private static void add(Map<String, List<String>> multiValueMap, String key, String value) {
+ if (isBlank(key)) {
+ return;
+ }
+ List<String> values = get(multiValueMap, key, true);
+ values.add(value);
+ }
+
+ private static <T extends Collection<String>> void addAll(Map<String, List<String>> multiValueMap,
+ Map<String, T> source) {
+ for (Map.Entry<String, T> entry : source.entrySet()) {
+ String key = entry.getKey();
+ for (String value : entry.getValue()) {
+ add(multiValueMap, key, value);
+ }
+ }
+ }
+
+ private static String getFirst(Map<String, List<String>> multiValueMap, String key) {
+ List<String> values = get(multiValueMap, key);
+ return CollectionUtils.isNotEmpty(values) ? values.get(0) : null;
+ }
+
+ private static List<String> get(Map<String, List<String>> multiValueMap, String key) {
+ return get(multiValueMap, key, false);
+ }
+
+ private static List<String> get(Map<String, List<String>> multiValueMap, String key, boolean createIfAbsent) {
+ return createIfAbsent ? multiValueMap.computeIfAbsent(key, k -> new LinkedList<>()) : multiValueMap.get(key);
+ }
+
+ public Map<String, List<String>> getHeaders() {
+ return unmodifiableMap(headers);
+ }
+
+ public void setHeaders(Map<String, List<String>> headers) {
+ headers(headers);
+ }
+
+ public Set<String> getConsumes() {
+ return consumes;
+ }
+
+ public void setConsumes(Set<String> consumes) {
+ this.consumes = consumes;
+ }
+
+ public Set<String> getProduces() {
+ return produces;
+ }
+
+ public void setProduces(Set<String> produces) {
+ this.produces = produces;
+ }
+
+ public Set<String> getParamNames() {
+ return params.keySet();
+ }
+
+ public Set<String> getHeaderNames() {
+ return headers.keySet();
+ }
+
+// public List<MediaType> getConsumeMediaTypes() {
+// return toMediaTypes(consumes);
+// }
+//
+// public List<MediaType> getProduceMediaTypes() {
+// return toMediaTypes(produces);
+// }
+
+ public String getParameter(String name) {
+ return this.getFirst(params, name);
+ }
+
+ public String getHeader(String name) {
+ return this.getFirst(headers, name);
+ }
+
+ public RequestMetadata addParam(String name, String value) {
+ add(params, name, value);
+ return this;
+ }
+
+ public RequestMetadata addHeader(String name, String value) {
+ add(headers, name, value);
+ return this;
+ }
+
+ private <T extends Collection<String>> RequestMetadata params(Map<String, T> params) {
+ addAll(this.params, params);
+ return this;
+ }
+
+ private <T extends Collection<String>> RequestMetadata headers(Map<String, List<String>> headers) {
+ if (headers != null && !headers.isEmpty()) {
+ Map<String, List<String>> httpHeaders = new LinkedHashMap<>();
+ // Add all headers
+ addAll(headers, httpHeaders);
+ // Handles "Content-Type" and "Accept" headers if present
+// mediaTypes(httpHeaders, HttpHeaders.CONTENT_TYPE, this.consumes);
+// mediaTypes(httpHeaders, HttpHeaders.ACCEPT, this.produces);
+ this.headers.putAll(httpHeaders);
+ }
+ return this;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof RequestMetadata)) {
+ return false;
+ }
+ RequestMetadata that = (RequestMetadata) o;
+ return Objects.equals(method, that.method) && Objects.equals(path, that.path)
+ && Objects.equals(consumes, that.consumes)
+ && Objects.equals(produces, that.produces) &&
+ // Metadata should not compare the values
+ Objects.equals(getParamNames(), that.getParamNames())
+ && Objects.equals(getHeaderNames(), that.getHeaderNames());
+
+ }
+
+ @Override
+ public int hashCode() {
+ // The values of metadata should not use for the hashCode() method
+ return Objects.hash(method, path, consumes, produces, getParamNames(),
+ getHeaderNames());
+ }
+
+ @Override
+ public String toString() {
+ return "RequestMetadata{" + "method='" + method + '\'' + ", path='" + path + '\''
+ + ", params=" + params + ", headers=" + headers + ", consumes=" + consumes
+ + ", produces=" + produces + '}';
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java
new file mode 100644
index 0000000..e43fce7
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RestMethodMetadata.java
@@ -0,0 +1,187 @@
+/*
+ * 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 org.apache.dubbo.metadata.rest;
+
+import org.apache.dubbo.metadata.definition.model.MethodDefinition;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import static java.util.Collections.emptyList;
+
+/**
+ * The metadata class for {@link RequestMetadata HTTP(REST) request} and
+ * its binding {@link MethodDefinition method definition}
+ *
+ * @since 2.7.5
+ */
+public class RestMethodMetadata implements Serializable {
+
+ private static final long serialVersionUID = 2935252016200830694L;
+
+ private MethodDefinition method;
+
+ private RequestMetadata request;
+
+ private Integer urlIndex;
+
+ private Integer bodyIndex;
+
+ private Integer headerMapIndex;
+
+ private String bodyType;
+
+ private Map<Integer, Collection<String>> indexToName;
+
+ private List<String> formParams;
+
+ private Map<Integer, Boolean> indexToEncoded;
+
+ public MethodDefinition getMethod() {
+ if (method == null) {
+ method = new MethodDefinition();
+ }
+ return method;
+ }
+
+ public void setMethod(MethodDefinition method) {
+ this.method = method;
+ }
+
+ public RequestMetadata getRequest() {
+ if (request == null) {
+ request = new RequestMetadata();
+ }
+ return request;
+ }
+
+ public void setRequest(RequestMetadata request) {
+ this.request = request;
+ }
+
+ public Integer getUrlIndex() {
+ return urlIndex;
+ }
+
+ public void setUrlIndex(Integer urlIndex) {
+ this.urlIndex = urlIndex;
+ }
+
+ public Integer getBodyIndex() {
+ return bodyIndex;
+ }
+
+ public void setBodyIndex(Integer bodyIndex) {
+ this.bodyIndex = bodyIndex;
+ }
+
+ public Integer getHeaderMapIndex() {
+ return headerMapIndex;
+ }
+
+ public void setHeaderMapIndex(Integer headerMapIndex) {
+ this.headerMapIndex = headerMapIndex;
+ }
+
+ public String getBodyType() {
+ return bodyType;
+ }
+
+ public void setBodyType(String bodyType) {
+ this.bodyType = bodyType;
+ }
+
+ public Map<Integer, Collection<String>> getIndexToName() {
+ if (indexToName == null) {
+ indexToName = new HashMap<>();
+ }
+ return indexToName;
+ }
+
+ public void setIndexToName(Map<Integer, Collection<String>> indexToName) {
+ this.indexToName = indexToName;
+ }
+
+ public void addIndexToName(Integer index, String name) {
+ Map<Integer, Collection<String>> indexToName = getIndexToName();
+ Collection<String> parameterNames = indexToName.computeIfAbsent(index, i -> new ArrayList<>(1));
+ parameterNames.add(name);
+ }
+
+ public boolean hasIndexedName(Integer index, String name) {
+ Map<Integer, Collection<String>> indexToName = getIndexToName();
+ return indexToName.getOrDefault(index, emptyList()).contains(name);
+ }
+
+ public List<String> getFormParams() {
+ return formParams;
+ }
+
+ public void setFormParams(List<String> formParams) {
+ this.formParams = formParams;
+ }
+
+ public Map<Integer, Boolean> getIndexToEncoded() {
+ return indexToEncoded;
+ }
+
+ public void setIndexToEncoded(Map<Integer, Boolean> indexToEncoded) {
+ this.indexToEncoded = indexToEncoded;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof RestMethodMetadata)) return false;
+ RestMethodMetadata that = (RestMethodMetadata) o;
+ return Objects.equals(getMethod(), that.getMethod()) &&
+ Objects.equals(getRequest(), that.getRequest()) &&
+ Objects.equals(getUrlIndex(), that.getUrlIndex()) &&
+ Objects.equals(getBodyIndex(), that.getBodyIndex()) &&
+ Objects.equals(getHeaderMapIndex(), that.getHeaderMapIndex()) &&
+ Objects.equals(getBodyType(), that.getBodyType()) &&
+ Objects.equals(getIndexToName(), that.getIndexToName()) &&
+ Objects.equals(getFormParams(), that.getFormParams()) &&
+ Objects.equals(getIndexToEncoded(), that.getIndexToEncoded());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getMethod(), getRequest(), getUrlIndex(), getBodyIndex(), getHeaderMapIndex(), getBodyType(), getIndexToName(), getFormParams(), getIndexToEncoded());
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("RestMethodMetadata{");
+ sb.append("method=").append(method);
+ sb.append(", request=").append(request);
+ sb.append(", urlIndex=").append(urlIndex);
+ sb.append(", bodyIndex=").append(bodyIndex);
+ sb.append(", headerMapIndex=").append(headerMapIndex);
+ sb.append(", bodyType='").append(bodyType).append('\'');
+ sb.append(", indexToName=").append(indexToName);
+ sb.append(", formParams=").append(formParams);
+ sb.append(", indexToEncoded=").append(indexToEncoded);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java
new file mode 100644
index 0000000..34cddd6
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ServiceRestMetadata.java
@@ -0,0 +1,103 @@
+/*
+ * 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 org.apache.dubbo.metadata.rest;
+
+import java.io.Serializable;
+import java.util.LinkedHashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * The metadata class for {@link RequestMetadata HTTP(REST) request} and
+ * its binding Dubbo service metadata
+ *
+ * @since 2.7.5
+ */
+public class ServiceRestMetadata implements Serializable {
+
+ private static final long serialVersionUID = -4549723140727443569L;
+
+ private String serviceInterface;
+
+ private String version;
+
+ private String group;
+
+ private Set<RestMethodMetadata> meta;
+
+ public String getServiceInterface() {
+ return serviceInterface;
+ }
+
+ public void setServiceInterface(String serviceInterface) {
+ this.serviceInterface = serviceInterface;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public Set<RestMethodMetadata> getMeta() {
+ if (meta == null) {
+ meta = new LinkedHashSet<>();
+ }
+ return meta;
+ }
+
+ public void setMeta(Set<RestMethodMetadata> meta) {
+ this.meta = meta;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ServiceRestMetadata)) return false;
+ ServiceRestMetadata that = (ServiceRestMetadata) o;
+ return Objects.equals(getServiceInterface(), that.getServiceInterface()) &&
+ Objects.equals(getVersion(), that.getVersion()) &&
+ Objects.equals(getGroup(), that.getGroup()) &&
+ Objects.equals(getMeta(), that.getMeta());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getServiceInterface(), getVersion(), getGroup(), getMeta());
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("ServiceRestMetadata{");
+ sb.append("serviceInterface='").append(serviceInterface).append('\'');
+ sb.append(", version='").append(version).append('\'');
+ sb.append(", group='").append(group).append('\'');
+ sb.append(", meta=").append(meta);
+ sb.append('}');
+ return sb.toString();
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java
index c751226..b23bab3 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java
@@ -4,20 +4,17 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.metadata.MetadataService;
-import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import java.util.Collection;
import java.util.Map;
import java.util.SortedSet;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
-import java.util.function.Function;
-import java.util.function.Supplier;
/**
* @author cvictory ON 2019-08-14
+ * @since 2.7.5
*/
public class BaseWritableMetadataService {
final Logger logger = LoggerFactory.getLogger(getClass());
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java
index eed9e43..448ddc8 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataServiceDelegate.java
@@ -1,7 +1,6 @@
package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.InmemoryConfiguration;
import org.apache.dubbo.metadata.WritableMetadataService;
import java.util.SortedSet;
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/util/HttpUtils.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/util/HttpUtils.java
new file mode 100644
index 0000000..20095a4
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/util/HttpUtils.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+package org.apache.dubbo.metadata.util;
+
+
+import org.apache.dubbo.common.utils.StringUtils;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableSet;
+import static org.apache.dubbo.common.utils.StringUtils.AND;
+import static org.apache.dubbo.common.utils.StringUtils.EQUAL;
+import static org.apache.dubbo.common.utils.StringUtils.QUESTION_MASK;
+import static org.apache.dubbo.common.utils.StringUtils.SLASH;
+import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
+import static org.apache.dubbo.common.utils.StringUtils.replace;
+
+/**
+ * Http Utilities class
+ *
+ * @since 2.7.5
+ */
+public abstract class HttpUtils {
+
+ private static final String UTF_8 = "UTF-8";
+
+ /**
+ * HTTP GET method.
+ */
+ public static final String GET = "GET";
+ /**
+ * HTTP POST method.
+ */
+ public static final String POST = "POST";
+ /**
+ * HTTP PUT method.
+ */
+ public static final String PUT = "PUT";
+ /**
+ * HTTP DELETE method.
+ */
+ public static final String DELETE = "DELETE";
+ /**
+ * HTTP HEAD method.
+ */
+ public static final String HEAD = "HEAD";
+ /**
+ * HTTP OPTIONS method.
+ */
+ public static final String OPTIONS = "OPTIONS";
+
+ /**
+ * The HTTP methods to support
+ */
+ public static final Set<String> HTTP_METHODS = unmodifiableSet(new LinkedHashSet<>(asList(
+ GET, POST, POST, PUT, DELETE, HEAD, OPTIONS
+ )));
+
+
+ public static String buildPath(String rootPath, String... subPaths) {
+
+ Set<String> paths = new LinkedHashSet<>();
+ paths.add(rootPath);
+ paths.addAll(asList(subPaths));
+
+ return normalizePath(paths.stream()
+ .filter(StringUtils::isNotEmpty)
+ .collect(Collectors.joining(SLASH)));
+ }
+
+ /**
+ * Normalize path:
+ * <ol>
+ * <li>To remove query string if presents</li>
+ * <li>To remove duplicated slash("/") if exists</li>
+ * </ol>
+ *
+ * @param path path to be normalized
+ * @return a normalized path if required
+ */
+ public static String normalizePath(String path) {
+ if (isEmpty(path)) {
+ return SLASH;
+ }
+ String normalizedPath = path;
+ int index = normalizedPath.indexOf(QUESTION_MASK);
+ if (index > -1) {
+ normalizedPath = normalizedPath.substring(0, index);
+ }
+ return replace(normalizedPath, "//", "/");
+ }
+
+// /**
+// * Get Parameters from the specified query string.
+// * <p>
+// *
+// * @param queryString The query string
+// * @return The query parameters
+// */
+// public static MultivaluedMap<String, String> getParameters(String queryString) {
+// return getParameters(split(queryString, AND_CHAR));
+// }
+
+// /**
+// * Get Parameters from the specified pairs of name-value.
+// * <p>
+// *
+// * @param pairs The pairs of name-value
+// * @return The query parameters
+// */
+// public static MultivaluedMap<String, String> getParameters(Iterable<String> pairs) {
+// MultivaluedMap<String, String> parameters = new MultivaluedHashMap<>();
+// if (pairs != null) {
+// for (String pair : pairs) {
+// String[] nameAndValue = split(pair, EQUAL_CHAR);
+// String name = decode(nameAndValue[0]);
+// String value = nameAndValue.length < 2 ? null : nameAndValue[1];
+// value = decode(value);
+// addParam(parameters, name, value);
+// }
+// }
+// return parameters;
+// }
+
+// /**
+// * Get Parameters from the specified pairs of name-value.
+// * <p>
+// *
+// * @param pairs The pairs of name-value
+// * @return The query parameters
+// */
+// public static MultivaluedMap<String, String> getParameters(String... pairs) {
+// return getParameters(asList(pairs));
+// }
+
+ // /**
+ // * Parse a read-only {@link MultivaluedMap} of {@link HttpCookie} from {@link
+ // HttpHeaders}
+ // *
+ // * @param httpHeaders {@link HttpHeaders}
+ // * @return non-null, the key is a cookie name , the value is {@link HttpCookie}
+ // */
+ // public static MultivaluedMap<String, HttpCookie> parseCookies(HttpHeaders
+ // httpHeaders) {
+ //
+ // String cookie = httpHeaders.getFirst(COOKIE);
+ //
+ // String[] cookieNameAndValues = StringUtils.delimitedListToStringArray(cookie,
+ // SEMICOLON);
+ //
+ // MultivaluedMap<String, HttpCookie> cookies = new
+ // LinkedMultiValueMap<>(cookieNameAndValues.length);
+ //
+ // for (String cookeNameAndValue : cookieNameAndValues) {
+ // String[] nameAndValue =
+ // delimitedListToStringArray(trimWhitespace(cookeNameAndValue), EQUAL);
+ // String name = nameAndValue[0];
+ // String value = nameAndValue.length < 2 ? null : nameAndValue[1];
+ // HttpCookie httpCookie = new HttpCookie(name, value);
+ // cookies.add(name, httpCookie);
+ // }
+ //
+ // return cookies;
+ // }
+
+ /**
+ * To the name and value line sets
+ *
+ * @param nameAndValuesMap the map of name and values
+ * @return non-null
+ */
+ public static Set<String> toNameAndValuesSet(
+ Map<String, List<String>> nameAndValuesMap) {
+ Set<String> nameAndValues = new LinkedHashSet<>();
+ for (Map.Entry<String, List<String>> entry : nameAndValuesMap.entrySet()) {
+ String name = entry.getKey();
+ List<String> values = entry.getValue();
+ for (String value : values) {
+ String nameAndValue = name + EQUAL + value;
+ nameAndValues.add(nameAndValue);
+ }
+ }
+ return nameAndValues;
+ }
+
+ public static String[] toNameAndValues(Map<String, List<String>> nameAndValuesMap) {
+ return toNameAndValuesSet(nameAndValuesMap).toArray(new String[0]);
+ }
+
+ /**
+ * Generate a string of query string from the specified request parameters {@link Map}
+ *
+ * @param params the specified request parameters {@link Map}
+ * @return non-null
+ */
+ public static String toQueryString(Map<String, List<String>> params) {
+ StringBuilder builder = new StringBuilder();
+ for (String line : toNameAndValuesSet(params)) {
+ builder.append(line).append(AND);
+ }
+ return builder.toString();
+ }
+
+ /**
+ * Decode value
+ *
+ * @param value the value requires to decode
+ * @return the decoded value
+ */
+ public static String decode(String value) {
+ if (value == null) {
+ return value;
+ }
+ String decodedValue = value;
+ try {
+ decodedValue = URLDecoder.decode(value, UTF_8);
+ } catch (UnsupportedEncodingException ex) {
+ }
+ return decodedValue;
+ }
+
+ /**
+ * encode value
+ *
+ * @param value the value requires to encode
+ * @return the encoded value
+ */
+ public static String encode(String value) {
+ String encodedValue = value;
+ try {
+ encodedValue = URLEncoder.encode(value, UTF_8);
+ } catch (UnsupportedEncodingException ex) {
+ }
+ return encodedValue;
+ }
+
+// private static void addParam(MultivaluedMap<String, String> paramsMap, String name,
+// String value) {
+// String paramValue = trim(value);
+// if (isEmpty(paramValue)) {
+// paramValue = EMPTY_VALUE;
+// }
+// paramsMap.add(trim(name), paramValue);
+// }
+}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java
index 9cb78a1..fd1bfe2 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/DynamicConfigurationServiceNameMappingTest.java
@@ -28,7 +28,7 @@ import java.util.TreeSet;
import static java.util.Arrays.asList;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
-import static org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping.buildKey;
+import static org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping.buildGroup;
import static org.apache.dubbo.metadata.ServiceNameMapping.getDefaultExtension;
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -54,10 +54,10 @@ public class DynamicConfigurationServiceNameMappingTest {
@Test
public void testBuildGroup() {
- assertEquals("test", buildKey("test", null, null, null));
- assertEquals("test", buildKey("test", "default", null, null));
- assertEquals("test", buildKey("test", "default", "1.0.0", null));
- assertEquals("test", buildKey("test", "default", "1.0.0", "dubbo"));
+ assertEquals("test", buildGroup("test", null, null, null));
+ assertEquals("test", buildGroup("test", "default", null, null));
+ assertEquals("test", buildGroup("test", "default", "1.0.0", null));
+ assertEquals("test", buildGroup("test", "default", "1.0.0", "dubbo"));
}
@Test
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifierTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifierTest.java
index 90df3db..3a58933 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifierTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/identifier/MetadataIdentifierTest.java
@@ -17,7 +17,6 @@
package org.apache.dubbo.metadata.report.identifier;
import org.apache.dubbo.metadata.MetadataConstants;
-import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java
index c032843..2bd9137 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataServiceTest.java
@@ -2,7 +2,6 @@ package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java
index b6dfa48..94cc577 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/store/RemoteWritableMeatadataServiceTest.java
@@ -18,7 +18,6 @@ package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
@@ -34,8 +33,6 @@ import org.junit.jupiter.api.Test;
import java.util.Map;
-import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
-
/**
* 2018/9/14
*/
diff --git a/dubbo-metadata/dubbo-metadata-processor/pom.xml b/dubbo-metadata/dubbo-metadata-processor/pom.xml
new file mode 100644
index 0000000..9be4ddb
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/pom.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata</artifactId>
+ <version>${revision}</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>dubbo-metadata-processor</artifactId>
+ <packaging>jar</packaging>
+ <name>dubbo-metadata-processor</name>
+ <description>The metadata processor module of Dubbo project</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata-api</artifactId>
+ <version>${project.parent.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-rpc-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-cluster</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-common</artifactId>
+ <version>${project.parent.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>javax.annotation</groupId>
+ <artifactId>javax.annotation-api</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-api</artifactId>
+ </exclusion>
+
+ <exclusion>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-core</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.javassist</groupId>
+ <artifactId>javassist</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.alibaba</groupId>
+ <artifactId>hessian-lite</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.alibaba</groupId>
+ <artifactId>fastjson</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>com.esotericsoftware</groupId>
+ <artifactId>kryo</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>de.javakaffee</groupId>
+ <artifactId>kryo-serializers</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>de.ruedigermoeller</groupId>
+ <artifactId>fst</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ </exclusion>
+ </exclusions>
+
+ </dependency>
+
+ <dependency>
+ <groupId>com.google.code.gson</groupId>
+ <artifactId>gson</artifactId>
+ </dependency>
+
+ <!-- Test -->
+ <dependency>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-config-api</artifactId>
+ <version>${project.parent.version}</version>
+ <scope>test</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-registry-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-metadata-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-monitor-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-remoting-api</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-rpc-injvm</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-filter-validation</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.apache.dubbo</groupId>
+ <artifactId>dubbo-filter-cache</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+
+ <!-- JAX-RS API -->
+ <dependency>
+ <groupId>javax.ws.rs</groupId>
+ <artifactId>javax.ws.rs-api</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- Spring Web MVC -->
+ <dependency>
+ <groupId>org.springframework</groupId>
+ <artifactId>spring-web</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/AbstractServiceAnnotationProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/AbstractServiceAnnotationProcessor.java
new file mode 100644
index 0000000..e5af1ad
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/AbstractServiceAnnotationProcessor.java
@@ -0,0 +1,108 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.PackageElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static javax.lang.model.util.ElementFilter.methodsIn;
+import static org.apache.dubbo.metadata.annotation.processing.util.ServiceAnnotationUtils.SUPPORTED_ANNOTATION_TYPES;
+
+/**
+ * Abstract {@link Processor} for the classes that were annotated by Dubbo's @Service
+ *
+ * @since 2.7.5
+ */
+public abstract class AbstractServiceAnnotationProcessor extends AbstractProcessor {
+
+ protected Elements elements;
+
+ private List<? extends Element> objectMembers;
+
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ this.elements = processingEnv.getElementUtils();
+ this.objectMembers = elements.getAllMembers(elements.getTypeElement(Object.class.getName()));
+ }
+
+ protected List<? extends Element> getActualMembers(TypeElement type) {
+ List<? extends Element> members = new LinkedList<>(elements.getAllMembers(type));
+ members.removeAll(objectMembers);
+ return members;
+ }
+
+ protected List<? extends ExecutableElement> getActualMethods(TypeElement type) {
+ return methodsIn(getActualMembers(type));
+ }
+
+ protected Map<String, ExecutableElement> getActualMethodsMap(TypeElement type) {
+ Map<String, ExecutableElement> methodsMap = new HashMap<>();
+ getActualMethods(type).forEach(method -> {
+ methodsMap.put(method.toString(), method);
+ });
+ return methodsMap;
+ }
+
+ public static String getMethodSignature(ExecutableElement method) {
+ if (!ElementKind.METHOD.equals(method.getKind())) {
+ throw new IllegalArgumentException("The argument must be Method Kind");
+ }
+
+ StringBuilder methodSignatureBuilder = new StringBuilder();
+
+ method.getModifiers().forEach(member -> {
+ methodSignatureBuilder.append(member).append(" ");
+ });
+
+ methodSignatureBuilder.append(method.getReturnType())
+ .append(" ")
+ .append(method.toString());
+
+ return methodSignatureBuilder.toString();
+ }
+
+ protected TypeElement getTypeElement(CharSequence className) {
+ return elements.getTypeElement(className);
+ }
+
+ protected PackageElement getPackageElement(Element type) {
+ return this.elements.getPackageOf(type);
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ @Override
+ public final Set<String> getSupportedAnnotationTypes() {
+ return SUPPORTED_ANNOTATION_TYPES;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ClassPathMetadataStorage.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ClassPathMetadataStorage.java
new file mode 100644
index 0000000..9e1032c
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ClassPathMetadataStorage.java
@@ -0,0 +1,105 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing;
+
+
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.tools.FileObject;
+import java.io.File;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import static java.util.Optional.empty;
+import static java.util.Optional.ofNullable;
+import static javax.tools.StandardLocation.CLASS_OUTPUT;
+import static org.apache.dubbo.metadata.annotation.processing.util.LoggerUtils.info;
+import static org.apache.dubbo.metadata.annotation.processing.util.LoggerUtils.warn;
+
+/**
+ * A storage class for metadata under class path
+ */
+public class ClassPathMetadataStorage {
+
+ private final Filer filer;
+
+ public ClassPathMetadataStorage(ProcessingEnvironment processingEnv) {
+ this.filer = processingEnv.getFiler();
+ }
+
+ public void write(Supplier<String> contentSupplier, String resourceName) {
+ try (Writer writer = getWriter(resourceName)) {
+ writer.write(contentSupplier.get());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public <T> Optional<T> read(String resourceName, Function<Reader, T> consumer) {
+ if (exists(resourceName)) {
+ try (Reader reader = getReader(resourceName)) {
+ return ofNullable(consumer.apply(reader));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return empty();
+ }
+
+ private boolean exists(String resourceName) {
+
+ return getResource(resourceName)
+ .map(FileObject::toUri)
+ .map(File::new)
+ .map(File::exists)
+ .orElse(false);
+ }
+
+ private Reader getReader(String resourceName) {
+ return getResource(resourceName).map(fileObject -> {
+ try {
+ return fileObject.openReader(false);
+ } catch (IOException e) {
+ }
+ return null;
+ }).orElse(null);
+ }
+
+ private FileObject createResource(String resourceName) throws IOException {
+ return filer.createResource(CLASS_OUTPUT, "", resourceName);
+ }
+
+ private Optional<FileObject> getResource(String resourceName) {
+ try {
+ FileObject fileObject = filer.getResource(CLASS_OUTPUT, "", resourceName);
+ return ofNullable(fileObject);
+ } catch (IOException e) {
+ warn(e.getMessage());
+ }
+ return empty();
+ }
+
+ private Writer getWriter(String resourceName) throws IOException {
+ FileObject fileObject = createResource(resourceName);
+ info("The resource[path : %s , deleted : %s] will be written", fileObject.toUri().getPath(), fileObject.delete());
+ return fileObject.openWriter();
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java
new file mode 100644
index 0000000..837cdec
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java
@@ -0,0 +1,60 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing;
+
+import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+
+import com.google.gson.Gson;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static javax.lang.model.util.ElementFilter.typesIn;
+import static org.apache.dubbo.metadata.annotation.processing.builder.ServiceDefinitionBuilder.build;
+
+/**
+ * The {@link Processor} class to generate the metadata of {@link ServiceDefinition} whose classes are annotated by Dubbo's @Service
+ *
+ * @see Processor
+ * @since 2.7.5
+ */
+public class ServiceDefinitionMetadataAnnotationProcessor extends AbstractServiceAnnotationProcessor {
+
+ private List<ServiceDefinition> serviceDefinitions = new LinkedList<>();
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+
+ typesIn(roundEnv.getRootElements()).forEach(serviceType -> process(processingEnv, serviceType, annotations));
+
+ if (roundEnv.processingOver()) {
+ ClassPathMetadataStorage writer = new ClassPathMetadataStorage(processingEnv);
+ writer.write(() -> new Gson().toJson(serviceDefinitions), "META-INF/dubbo/service-definitions.json");
+ }
+
+ return false;
+ }
+
+ private void process(ProcessingEnvironment processingEnv, TypeElement serviceType, Set<? extends TypeElement> annotations) {
+ serviceDefinitions.add(build(processingEnv, serviceType));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java
new file mode 100644
index 0000000..d7ebc3a
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.TypeMirror;
+import java.lang.reflect.Array;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isArrayType;
+
+/**
+ * {@link TypeDefinitionBuilder} for Java {@link Array}
+ *
+ * @since 2.7.5
+ */
+public class ArrayTypeDefinitionBuilder implements TypeDefinitionBuilder<ArrayType> {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
+ return isArrayType(type);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, ArrayType type, TypeDefinition typeDefinition) {
+ TypeMirror componentType = type.getComponentType();
+ typeDefinition.getItems().add(TypeDefinitionBuilder.build(processingEnv, componentType));
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY - 4;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java
new file mode 100644
index 0000000..3ed2b45
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilder.java
@@ -0,0 +1,61 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import java.util.Collection;
+import java.util.Objects;
+
+/**
+ * {@link TypeDefinitionBuilder} for Java {@link Collection}
+ *
+ * @since 2.7.5
+ */
+public class CollectionTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, DeclaredType type) {
+ Elements elements = processingEnv.getElementUtils();
+ TypeElement collectionTypeElement = elements.getTypeElement(Collection.class.getTypeName());
+ TypeMirror collectionType = collectionTypeElement.asType();
+ Types types = processingEnv.getTypeUtils();
+ TypeMirror erasedType = types.erasure(type);
+ return types.isAssignable(erasedType, collectionType);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+ // Generic Type arguments
+ type.getTypeArguments()
+ .stream()
+ .map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument)) // build the TypeDefinition from typeArgument
+ .filter(Objects::nonNull)
+ .forEach(typeDefinition.getItems()::add); // Add into the declared TypeDefinition
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY - 5;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java
new file mode 100644
index 0000000..b12dcef
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/DeclaredTypeDefinitionBuilder.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofDeclaredType;
+
+/**
+ * An interface of {@link TypeDefinitionBuilder} for {@link DeclaredType}
+ *
+ * @since 2.7.5
+ */
+public interface DeclaredTypeDefinitionBuilder extends TypeDefinitionBuilder<DeclaredType> {
+
+ @Override
+ default boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ if (declaredType == null) {
+ return false;
+ }
+ return accept(processingEnv, declaredType);
+ }
+
+ /**
+ * Test the specified {@link DeclaredType type} is accepted or not
+ *
+ * @param processingEnv {@link ProcessingEnvironment}
+ * @param type {@link DeclaredType type}
+ * @return <code>true</code> if accepted
+ */
+ boolean accept(ProcessingEnvironment processingEnv, DeclaredType type);
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java
new file mode 100644
index 0000000..c0ed002
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilder.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.util.FieldUtils;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Name;
+import javax.lang.model.type.DeclaredType;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.getDeclaredFields;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isEnumType;
+
+/**
+ * {@link TypeDefinitionBuilder} for Java {@link Enum}
+ *
+ * @since 2.7.5
+ */
+public class EnumTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, DeclaredType type) {
+ return isEnumType(type);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+ getDeclaredFields(type, FieldUtils::isEnumMemberField)
+ .stream()
+ .map(Element::getSimpleName)
+ .map(Name::toString)
+ .forEach(typeDefinition.getEnums()::add);
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY - 2;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java
new file mode 100644
index 0000000..f9c648c
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilder.java
@@ -0,0 +1,65 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.getNonStaticFields;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getType;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isClassType;
+
+/**
+ * {@link TypeDefinitionBuilder} for General Object
+ *
+ * @since 2.7.5
+ */
+public class GeneralTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, DeclaredType type) {
+ return isClassType(type);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+
+ String typeName = type.toString();
+
+ TypeElement typeElement = getType(processingEnv, typeName);
+
+ buildProperties(processingEnv, typeElement, typeDefinition);
+ }
+
+ protected void buildProperties(ProcessingEnvironment processingEnv, TypeElement type, TypeDefinition definition) {
+ getNonStaticFields(type).forEach(field -> {
+ String fieldName = field.getSimpleName().toString();
+ TypeDefinition propertyType = TypeDefinitionBuilder.build(processingEnv, field);
+ if (propertyType != null) {
+ definition.getProperties().put(fieldName, propertyType);
+ }
+ });
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java
new file mode 100644
index 0000000..a0a204d
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilder.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * {@link TypeDefinitionBuilder} for Java {@link Map}
+ *
+ * @since 2.7.5
+ */
+public class MapTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, DeclaredType type) {
+ Elements elements = processingEnv.getElementUtils();
+ TypeElement mapTypeElement = elements.getTypeElement(Map.class.getTypeName());
+ TypeMirror mapType = mapTypeElement.asType();
+ Types types = processingEnv.getTypeUtils();
+ TypeMirror erasedType = types.erasure(type);
+ return types.isAssignable(erasedType, mapType);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+ // Generic Type arguments
+ type.getTypeArguments()
+ .stream()
+ .map(typeArgument -> TypeDefinitionBuilder.build(processingEnv, typeArgument)) // build the TypeDefinition from typeArgument
+ .filter(Objects::nonNull)
+ .forEach(typeDefinition.getItems()::add); // Add into the declared TypeDefinition
+
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY - 6;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java
new file mode 100644
index 0000000..c2bad78
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/MethodDefinitionBuilder.java
@@ -0,0 +1,53 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.MethodDefinition;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getMethodName;
+import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getMethodParameterTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getReturnType;
+
+/**
+ * A Builder class for {@link MethodDefinition}
+ *
+ * @see MethodDefinition
+ * @since 2.7.5
+ */
+public interface MethodDefinitionBuilder {
+
+ static MethodDefinition build(ProcessingEnvironment processingEnv, ExecutableElement method) {
+ MethodDefinition methodDefinition = new MethodDefinition();
+ methodDefinition.setName(getMethodName(method));
+ methodDefinition.setReturnType(getReturnType(method));
+ methodDefinition.setParameterTypes(getMethodParameterTypes(method));
+ methodDefinition.setParameters(getMethodParameters(processingEnv, method));
+ return methodDefinition;
+ }
+
+ static List<TypeDefinition> getMethodParameters(ProcessingEnvironment processingEnv, ExecutableElement method) {
+ return method.getParameters().stream()
+ .map(element -> TypeDefinitionBuilder.build(processingEnv, element))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java
new file mode 100644
index 0000000..903c15f
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilder.java
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeMirror;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isPrimitiveType;
+
+/**
+ * {@link TypeDefinitionBuilder} for Java {@link PrimitiveType primitve type}
+ *
+ * @since 2.7.5
+ */
+public class PrimitiveTypeDefinitionBuilder implements TypeDefinitionBuilder<PrimitiveType> {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, TypeMirror type) {
+ return isPrimitiveType(type);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, PrimitiveType type, TypeDefinition typeDefinition) {
+ // DO NOTHING
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY - 3;
+ }
+}
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java
new file mode 100644
index 0000000..8563e00
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilder.java
@@ -0,0 +1,56 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getPublicNonStaticMethods;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getResourceName;
+
+/**
+ * A Builder for {@link ServiceDefinition}
+ *
+ * @see ServiceDefinition
+ * @since 2.7.5
+ */
+public interface ServiceDefinitionBuilder {
+
+ static ServiceDefinition build(ProcessingEnvironment processingEnv, TypeElement type) {
+ ServiceDefinition serviceDefinition = new ServiceDefinition();
+ serviceDefinition.setCanonicalName(type.toString());
+ serviceDefinition.setCodeSource(getResourceName(type.toString()));
+
+ // Get all super types and interface excluding the specified type
+ // and then the result will be added into ServiceDefinition#getTypes()
+ getHierarchicalTypes(type.asType(), Object.class)
+ .stream()
+ .map(t -> TypeDefinitionBuilder.build(processingEnv, t))
+ .forEach(serviceDefinition.getTypes()::add);
+
+ // Get all declared methods that will be added into ServiceDefinition#getMethods()
+ getPublicNonStaticMethods(type, Object.class)
+ .stream()
+ .map(method -> MethodDefinitionBuilder.build(processingEnv, method))
+ .forEach(serviceDefinition.getMethods()::add);
+
+ return serviceDefinition;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java
new file mode 100644
index 0000000..634d7be
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilder.java
@@ -0,0 +1,49 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.util.TypeUtils;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.type.DeclaredType;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isSimpleType;
+
+
+/**
+ * {@link TypeDefinitionBuilder} for {@link TypeUtils#SIMPLE_TYPES Java Simple Type}
+ *
+ * @since 2.7.5
+ */
+public class SimpleTypeDefinitionBuilder implements DeclaredTypeDefinitionBuilder {
+
+ @Override
+ public boolean accept(ProcessingEnvironment processingEnv, DeclaredType type) {
+ return isSimpleType(type);
+ }
+
+ @Override
+ public void build(ProcessingEnvironment processingEnv, DeclaredType type, TypeDefinition typeDefinition) {
+ // DO NOTHING
+ }
+
+ @Override
+ public int getPriority() {
+ return MIN_PRIORITY - 1;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java
new file mode 100644
index 0000000..c336022
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/builder/TypeDefinitionBuilder.java
@@ -0,0 +1,95 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.type.TypeMirror;
+
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+
+
+/**
+ * A class builds the instance of {@link TypeDefinition}
+ *
+ * @since 2.7.5
+ */
+@SPI
+public interface TypeDefinitionBuilder<T extends TypeMirror> extends Prioritized {
+
+ /**
+ * Test the specified {@link TypeMirror type} is accepted or not
+ *
+ * @param processingEnv {@link ProcessingEnvironment}
+ * @param type {@link TypeMirror type}
+ * @return <code>true</code> if accepted
+ */
+ boolean accept(ProcessingEnvironment processingEnv, TypeMirror type);
+
+ /**
+ * Build the instance of {@link TypeDefinition}
+ *
+ * @param processingEnv {@link ProcessingEnvironment}
+ * @param type {@link T type}
+ * @param typeDefinition {@link TypeDefinition} to be built
+ * @return an instance of {@link TypeDefinition}
+ */
+ void build(ProcessingEnvironment processingEnv, T type, TypeDefinition typeDefinition);
+
+ /**
+ * Build the instance of {@link TypeDefinition} from the specified {@link Element element}
+ *
+ * @param processingEnv {@link ProcessingEnvironment}
+ * @param element {@link Element source element}
+ * @return non-null
+ */
+ static TypeDefinition build(ProcessingEnvironment processingEnv, Element element) {
+ TypeDefinition typeDefinition = build(processingEnv, element.asType());
+ typeDefinition.set$ref(element.toString());
+ return typeDefinition;
+ }
+
+ /**
+ * Build the instance of {@link TypeDefinition} from the specified {@link TypeMirror type}
+ *
+ * @param processingEnv {@link ProcessingEnvironment}
+ * @param type {@link TypeMirror type}
+ * @return non-null
+ */
+ static TypeDefinition build(ProcessingEnvironment processingEnv, TypeMirror type) {
+ String typeName = type.toString();
+ TypeDefinition typeDefinition = new TypeDefinition(typeName);
+
+ // Build by all instances of TypeDefinitionBuilder that were loaded By Java SPI
+// load(TypeDefinitionBuilder.class, TypeDefinitionBuilder.class.getClassLoader())
+ getExtensionLoader(TypeDefinitionBuilder.class)
+ .getSupportedExtensionInstances()
+ .stream()
+ .filter(builder -> builder.accept(processingEnv, type))
+ .findFirst()
+ .ifPresent(builder -> {
+ builder.build(processingEnv, type, typeDefinition);
+ // typeDefinition.setTypeBuilderName(builder.getClass().getName());
+ });
+
+ return typeDefinition;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractAnnotatedMethodParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractAnnotatedMethodParameterProcessor.java
new file mode 100644
index 0000000..51ef786
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractAnnotatedMethodParameterProcessor.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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+import static org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor.buildDefaultValue;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getValue;
+
+/**
+ * The abstract {@link AnnotatedMethodParameterProcessor} implementation
+ *
+ * @since 2.7.5
+ */
+public abstract class AbstractAnnotatedMethodParameterProcessor implements AnnotatedMethodParameterProcessor {
+
+ @Override
+ public final void process(AnnotationMirror annotation, VariableElement parameter, int parameterIndex, ExecutableElement method, RestMethodMetadata restMethodMetadata) {
+ String annotationValue = getAnnotationValue(annotation, parameter, parameterIndex);
+ String defaultValue = getDefaultValue(annotation, parameter, parameterIndex);
+ process(annotationValue, defaultValue, annotation, parameter, parameterIndex, method, restMethodMetadata);
+ }
+
+ protected abstract void process(String annotationValue, String defaultValue, AnnotationMirror annotation, VariableElement parameter, int parameterIndex,
+ ExecutableElement method, RestMethodMetadata restMethodMetadata);
+
+ protected String getAnnotationValue(AnnotationMirror annotation, VariableElement parameter, int parameterIndex) {
+ return getValue(annotation);
+ }
+
+ protected String getDefaultValue(AnnotationMirror annotation, VariableElement parameter, int parameterIndex) {
+ return buildDefaultValue(parameterIndex);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataProcessor.java
new file mode 100644
index 0000000..c58cc36
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AbstractServiceRestMetadataProcessor.java
@@ -0,0 +1,234 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import org.apache.dubbo.metadata.definition.model.MethodDefinition;
+import org.apache.dubbo.metadata.rest.RequestMetadata;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import static java.lang.ThreadLocal.withInitial;
+import static java.util.Collections.emptyList;
+import static java.util.Optional.empty;
+import static java.util.Optional.of;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+import static org.apache.dubbo.metadata.annotation.processing.builder.MethodDefinitionBuilder.build;
+import static org.apache.dubbo.metadata.annotation.processing.util.LoggerUtils.info;
+import static org.apache.dubbo.metadata.annotation.processing.util.MethodUtils.getPublicNonStaticMethods;
+import static org.apache.dubbo.metadata.annotation.processing.util.ServiceAnnotationUtils.getAnnotation;
+import static org.apache.dubbo.metadata.annotation.processing.util.ServiceAnnotationUtils.getGroup;
+import static org.apache.dubbo.metadata.annotation.processing.util.ServiceAnnotationUtils.getVersion;
+import static org.apache.dubbo.metadata.annotation.processing.util.ServiceAnnotationUtils.resolveServiceInterfaceName;
+
+/**
+ * Abstract {@link ServiceRestMetadataProcessor} implementation
+ *
+ * @since 2.7.5
+ */
+public abstract class AbstractServiceRestMetadataProcessor implements ServiceRestMetadataProcessor {
+
+ private final static ThreadLocal<Map<String, Object>> threadLocalCache = withInitial(HashMap::new);
+
+ private final static Map<String, List<AnnotatedMethodParameterProcessor>> parameterProcessorsMap = loadAnnotatedMethodParameterProcessors();
+
+ private final String processorName = getClass().getSimpleName();
+
+ @Override
+ public final ServiceRestMetadata process(ProcessingEnvironment processingEnv,
+ TypeElement serviceType,
+ Set<? extends TypeElement> annotations) {
+
+ info("%s is processing the service type[%s] with annotations[%s]", processorName, serviceType,
+ annotations.stream().map(t -> "@" + t.toString()).collect(Collectors.joining(",")));
+
+ ServiceRestMetadata serviceRestMetadata = new ServiceRestMetadata();
+
+ try {
+ AnnotationMirror serviceAnnotation = getAnnotation(serviceType);
+ serviceRestMetadata.setServiceInterface(resolveServiceInterfaceName(serviceType, serviceAnnotation));
+ serviceRestMetadata.setGroup(getGroup(serviceAnnotation));
+ serviceRestMetadata.setVersion(getVersion(serviceAnnotation));
+
+ List<? extends ExecutableElement> methods = getPublicNonStaticMethods(serviceType, Object.class);
+
+ methods.forEach(method -> {
+ processRestMethodMetadata(processingEnv, serviceType, method)
+ .ifPresent(serviceRestMetadata.getMeta()::add);
+ });
+ } finally {
+ clearCache();
+ }
+
+ info("The %s's process result : %s", processorName, serviceRestMetadata);
+
+ return serviceRestMetadata;
+ }
+
+ protected Optional<RestMethodMetadata> processRestMethodMetadata(ProcessingEnvironment processingEnv,
+ TypeElement serviceType, ExecutableElement method) {
+
+ String requestPath = getRequestPath(processingEnv, serviceType, method); // requestPath is required
+
+ if (requestPath == null) {
+ return empty();
+ }
+
+ String requestMethod = getRequestMethod(processingEnv, serviceType, method); // requestMethod is required
+
+ if (requestMethod == null) {
+ return empty();
+ }
+
+ RestMethodMetadata metadata = new RestMethodMetadata();
+
+ MethodDefinition methodDefinition = getMethodDefinition(processingEnv, serviceType, method);
+ // Set MethodDefinition
+ metadata.setMethod(methodDefinition);
+
+ // process the annotated method parameters
+ processAnnotatedMethodParameters(method, serviceType, metadata);
+
+ // process produces
+ Set<String> produces = new LinkedHashSet<>();
+ processProduces(processingEnv, serviceType, method, produces);
+
+ // process consumes
+ Set<String> consumes = new LinkedHashSet<>();
+ processConsumes(processingEnv, serviceType, method, consumes);
+
+ // Initialize RequestMetadata
+ RequestMetadata request = metadata.getRequest();
+ request.setPath(requestPath);
+ request.setMethod(requestMethod);
+ request.setProduces(produces);
+ request.setConsumes(consumes);
+
+ // Post-Process
+ postProcessRestMethodMetadata(processingEnv, serviceType, method, metadata);
+
+ return of(metadata);
+ }
+
+ /**
+ * Post-Process for {@link RestMethodMetadata}, sub-type could override this method for further works
+ *
+ * @param processingEnv {@link ProcessingEnvironment}
+ * @param serviceType The type that @Service annotated
+ * @param method The public method of <code>serviceType</code>
+ * @param metadata {@link RestMethodMetadata} maybe updated
+ */
+ protected void postProcessRestMethodMetadata(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, RestMethodMetadata metadata) {
+ }
+
+ protected abstract String getRequestPath(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method);
+
+ protected abstract String getRequestMethod(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method);
+
+ protected MethodDefinition getMethodDefinition(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method) {
+ return build(processingEnv, method);
+ }
+
+ protected void processAnnotatedMethodParameters(ExecutableElement method, TypeElement type,
+ RestMethodMetadata metadata) {
+ List<? extends VariableElement> methodParameters = method.getParameters();
+ int size = methodParameters.size();
+ for (int i = 0; i < size; i++) {
+ VariableElement parameter = methodParameters.get(i);
+ // Add indexed parameter name
+ metadata.addIndexToName(i, parameter.getSimpleName().toString());
+ processAnnotatedMethodParameter(parameter, i, method, type, metadata);
+ }
+ }
+
+ protected void processAnnotatedMethodParameter(VariableElement parameter, int parameterIndex,
+ ExecutableElement method, TypeElement serviceType,
+ RestMethodMetadata metadata) {
+
+ parameter.getAnnotationMirrors().forEach(annotation -> {
+ String annotationType = annotation.getAnnotationType().toString();
+ parameterProcessorsMap.getOrDefault(annotationType, emptyList())
+ .forEach(parameterProcessor -> {
+ parameterProcessor.process(annotation, parameter, parameterIndex, method, metadata);
+ });
+ });
+ }
+
+ protected abstract void processProduces(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> produces);
+
+ protected abstract void processConsumes(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> consumes);
+
+ protected static final void put(String name, Object value) {
+ Map<String, Object> cache = getCache();
+ cache.put(name, value);
+ }
+
+ protected static final <T> T get(String name) throws ClassCastException {
+ Map<String, Object> cache = getCache();
+ return (T) cache.get(name);
+ }
+
+ protected static final <V> V computeIfAbsent(String name, Function<? super String, ? extends V> mappingFunction) {
+ return (V) getCache().computeIfAbsent(name, mappingFunction);
+ }
+
+ private static Map<String, List<AnnotatedMethodParameterProcessor>> loadAnnotatedMethodParameterProcessors() {
+ Map<String, List<AnnotatedMethodParameterProcessor>> parameterProcessorsMap = new LinkedHashMap<>();
+
+// load(AnnotatedMethodParameterProcessor.class, AnnotatedMethodParameterProcessor.class.getClassLoader())
+ getExtensionLoader(AnnotatedMethodParameterProcessor.class)
+ .getSupportedExtensionInstances()
+ .forEach(processor -> {
+ List<AnnotatedMethodParameterProcessor> processors =
+ parameterProcessorsMap.computeIfAbsent(processor.getAnnotationType(), k -> new LinkedList<>());
+ processors.add(processor);
+ });
+
+ return parameterProcessorsMap;
+ }
+
+ private static Map<String, Object> getCache() {
+ return threadLocalCache.get();
+ }
+
+ private static void clearCache() {
+ Map<String, Object> cache = getCache();
+ cache.clear();
+ threadLocalCache.remove();
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AnnotatedMethodParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AnnotatedMethodParameterProcessor.java
new file mode 100644
index 0000000..9922455
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/AnnotatedMethodParameterProcessor.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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+/**
+ * The interface to process the parameter of method that was annotated
+ *
+ * @since 2.7.5
+ */
+@SPI
+public interface AnnotatedMethodParameterProcessor extends Prioritized {
+
+ /**
+ * The string presenting the annotation type
+ *
+ * @return non-null
+ */
+ String getAnnotationType();
+
+ /**
+ * Process the specified method {@link VariableElement parameter}
+ *
+ * @param annotation {@link AnnotationMirror the target annotation} whose type is {@link #getAnnotationType()}
+ * @param parameter {@link VariableElement method parameter}
+ * @param parameterIndex the index of parameter in the method
+ * @param method {@link ExecutableElement method that parameter belongs to}
+ * @param restMethodMetadata {@link RestMethodMetadata the metadata is used to update}
+ */
+ void process(AnnotationMirror annotation, VariableElement parameter, int parameterIndex, ExecutableElement method,
+ RestMethodMetadata restMethodMetadata);
+
+
+ /**
+ * Build the default value
+ *
+ * @param parameterIndex the index of parameter
+ * @return the placeholder
+ */
+ static String buildDefaultValue(int parameterIndex) {
+ return "{" + parameterIndex + "}";
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/DefaultServiceRestMetadataProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/DefaultServiceRestMetadataProcessor.java
new file mode 100644
index 0000000..73772db
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/DefaultServiceRestMetadataProcessor.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import java.util.Set;
+
+/**
+ * The default implementation of {@link ServiceRestMetadataProcessor}
+ *
+ * @since 2.7.5
+ */
+public class DefaultServiceRestMetadataProcessor extends AbstractServiceRestMetadataProcessor {
+
+ @Override
+ public boolean supports(ProcessingEnvironment processingEnvironment, TypeElement serviceType) {
+ return true;
+ }
+
+ @Override
+ protected String getRequestPath(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method) {
+ return null;
+ }
+
+ @Override
+ protected String getRequestMethod(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method) {
+ return null;
+ }
+
+ @Override
+ protected void processProduces(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> produces) {
+
+ }
+
+ @Override
+ protected void processConsumes(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> consumes) {
+
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataAnnotationProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataAnnotationProcessor.java
new file mode 100644
index 0000000..9192e04
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataAnnotationProcessor.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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractServiceAnnotationProcessor;
+import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.Processor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.TypeElement;
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import static javax.lang.model.util.ElementFilter.typesIn;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+import static org.apache.dubbo.metadata.annotation.processing.util.ServiceAnnotationUtils.isServiceAnnotationPresent;
+
+/**
+ * The {@link Processor} class to generate the metadata of REST from the classes that are annotated by Dubbo's
+ *
+ * @Service
+ * @see Processor
+ * @since 2.7.5
+ */
+public class ServiceRestMetadataAnnotationProcessor extends AbstractServiceAnnotationProcessor {
+
+ private List<ServiceRestMetadataProcessor> metadataProcessors;
+
+ private ServiceRestMetadataStorage serviceRestMetadataWriter;
+
+ private Set<ServiceRestMetadata> serviceRestMetadata = new LinkedHashSet<>();
+
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ this.metadataProcessors = new LinkedList<>(getExtensionLoader(ServiceRestMetadataProcessor.class).getSupportedExtensionInstances());
+ this.serviceRestMetadataWriter = new ServiceRestMetadataStorage(processingEnv);
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+
+ typesIn(roundEnv.getRootElements()).forEach(serviceType -> process(processingEnv, serviceType, annotations));
+
+ if (roundEnv.processingOver()) {
+ try {
+ serviceRestMetadataWriter.append(serviceRestMetadata);
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ return false;
+ }
+
+ private void process(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ Set<? extends TypeElement> annotations) {
+ metadataProcessors
+ .stream()
+ .filter(processor -> supports(processor, processingEnv, serviceType))
+ .map(processor -> processor.process(processingEnv, serviceType, annotations))
+ .forEach(serviceRestMetadata::add);
+ }
+
+ private boolean supports(ServiceRestMetadataProcessor processor, ProcessingEnvironment processingEnv,
+ TypeElement serviceType) {
+ // @Service must be present in service type
+ return isServiceAnnotationPresent(serviceType) && processor.supports(processingEnv, serviceType);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataProcessor.java
new file mode 100644
index 0000000..1e5c5b9
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataProcessor.java
@@ -0,0 +1,55 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.lang.Prioritized;
+import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import java.util.Set;
+
+/**
+ * The class to process {@link ServiceRestMetadata} based on Annotation Processor Tool
+ *
+ * @since 2.7.5
+ */
+@SPI
+public interface ServiceRestMetadataProcessor extends Prioritized {
+
+ /**
+ * Supports or not to the specified service type
+ *
+ * @param processingEnvironment {@link ProcessingEnvironment}
+ * @param serviceType Dubbo service type or interface
+ * @return if supports, return <code>true</code>, or <code>false</code>
+ */
+ boolean supports(ProcessingEnvironment processingEnvironment, TypeElement serviceType);
+
+ /**
+ * Process the {@link ServiceRestMetadata} from given service type
+ *
+ * @param processingEnvironment {@link ProcessingEnvironment}
+ * @param serviceType Dubbo service type or interface
+ * @param annotations
+ * @return non-null
+ */
+ ServiceRestMetadata process(ProcessingEnvironment processingEnvironment,
+ TypeElement serviceType,
+ Set<? extends TypeElement> annotations);
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java
new file mode 100644
index 0000000..7365363
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java
@@ -0,0 +1,66 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest;
+
+import org.apache.dubbo.metadata.annotation.processing.ClassPathMetadataStorage;
+import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
+
+import com.google.gson.Gson;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import static com.google.gson.reflect.TypeToken.getParameterized;
+
+/**
+ * The storage for {@link ServiceRestMetadata}
+ */
+public class ServiceRestMetadataStorage {
+
+ public static final String METADATA_RESOURCE_PATH = "META-INF/dubbo/service-rest-metadata.json";
+
+ private final ClassPathMetadataStorage storage;
+
+ public ServiceRestMetadataStorage(ProcessingEnvironment processingEnv) {
+ this.storage = new ClassPathMetadataStorage(processingEnv);
+ }
+
+ public void append(Set<ServiceRestMetadata> serviceRestMetadata) throws IOException {
+ Set<ServiceRestMetadata> allServiceRestMetadata = new LinkedHashSet<>();
+ storage.read(METADATA_RESOURCE_PATH, reader -> {
+ Gson gson = new Gson();
+ return (List) gson.fromJson(reader, getParameterized(List.class, ServiceRestMetadata.class).getType());
+ }).ifPresent(existedMetadata -> {
+ // Add all existed ServiceRestMetadata
+ allServiceRestMetadata.addAll(existedMetadata);
+ });
+ // Add all new ServiceRestMetadata
+ allServiceRestMetadata.addAll(serviceRestMetadata);
+ write(serviceRestMetadata);
+ }
+
+ public void write(Set<ServiceRestMetadata> serviceRestMetadata) throws IOException {
+ if (serviceRestMetadata.isEmpty()) {
+ return;
+ }
+ storage.write(() -> new Gson().toJson(serviceRestMetadata), METADATA_RESOURCE_PATH);
+ }
+
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java
new file mode 100644
index 0000000..0818ff3
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/DefaultValueParameterProcessor.java
@@ -0,0 +1,78 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AbstractAnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.rest.RequestMetadata;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @DefaultValue
+ * *
+ *
+ * @since 2.7.5
+ */
+public class DefaultValueParameterProcessor extends AbstractAnnotatedMethodParameterProcessor {
+
+ /**
+ * The annotation class name of @DefaultValue
+ */
+ public static final String DEFAULT_VALUE_ANNOTATION_CLASS_NAME = "javax.ws.rs.DefaultValue";
+
+ @Override
+ public String getAnnotationType() {
+ return DEFAULT_VALUE_ANNOTATION_CLASS_NAME;
+ }
+
+ @Override
+ protected void process(String annotationValue, String defaultValue, AnnotationMirror annotation, VariableElement parameter, int parameterIndex, ExecutableElement method, RestMethodMetadata restMethodMetadata) {
+ RequestMetadata requestMetadata = restMethodMetadata.getRequest();
+
+ // process the request parameters
+ setDefaultValue(requestMetadata.getParams(), defaultValue, annotationValue);
+ // process the request headers
+ setDefaultValue(requestMetadata.getHeaders(), defaultValue, annotationValue);
+
+ }
+
+ private void setDefaultValue(Map<String, List<String>> source, String placeholderValue, String defaultValue) {
+ OUTTER:
+ for (Map.Entry<String, List<String>> entry : source.entrySet()) {
+ List<String> values = entry.getValue();
+ int size = values.size();
+ for (int i = 0; i < size; i++) {
+ String value = values.get(i);
+ if (placeholderValue.equals(value)) {
+ values.set(i, defaultValue);
+ break OUTTER;
+ }
+ }
+ }
+ }
+
+ public int getPriority() {
+ return MIN_PRIORITY;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/FormParamParameterProcessor.java
similarity index 55%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/FormParamParameterProcessor.java
index 29cd637..c323e8a 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/FormParamParameterProcessor.java
@@ -14,24 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
/**
- * {@link Class} Utilities
- * <p>
- * The source code is cloned from
- * https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/util/ClassUtils.java
+ * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @FormParam
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ClassUtils {
+public class FormParamParameterProcessor extends ParamAnnotationParameterProcessor {
- public static <T> Class<T> resolveGenericType(Class<?> declaredClass) {
- ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass();
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- return (Class<T>) actualTypeArguments[0];
+ @Override
+ public String getAnnotationType() {
+ return "javax.ws.rs.FormParam";
}
}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/HeaderParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/HeaderParamParameterProcessor.java
new file mode 100644
index 0000000..278cf93
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/HeaderParamParameterProcessor.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AbstractAnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.rest.RequestMetadata;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+import static org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor.buildDefaultValue;
+
+/**
+ * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @HeaderParam
+ *
+ * @since 2.7.5
+ */
+public class HeaderParamParameterProcessor extends AbstractAnnotatedMethodParameterProcessor {
+
+ @Override
+ public String getAnnotationType() {
+ return "javax.ws.rs.HeaderParam";
+ }
+
+ @Override
+ protected void process(String headerName, String defaultValue, AnnotationMirror annotation,
+ VariableElement parameter, int parameterIndex,
+ ExecutableElement method, RestMethodMetadata restMethodMetadata) {
+ RequestMetadata requestMetadata = restMethodMetadata.getRequest();
+ // Add the placeholder as header value
+ requestMetadata.addHeader(headerName, buildDefaultValue(parameterIndex));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/JAXRSServiceRestMetadataProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/JAXRSServiceRestMetadataProcessor.java
new file mode 100644
index 0000000..564760f
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/JAXRSServiceRestMetadataProcessor.java
@@ -0,0 +1,113 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AbstractServiceRestMetadataProcessor;
+import org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataProcessor;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.AnnotatedConstruct;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.findAnnotation;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.findMetaAnnotation;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getAnnotation;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getValue;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.isAnnotationPresent;
+import static org.apache.dubbo.metadata.util.HttpUtils.buildPath;
+
+/**
+ * {@link ServiceRestMetadataProcessor} implementation for JAX-RS 2 and 1
+ *
+ * @since 2.7.5
+ */
+public class JAXRSServiceRestMetadataProcessor extends AbstractServiceRestMetadataProcessor {
+
+ /**
+ * The annotation name of @Path
+ */
+ public static final String PATH_ANNOTATION_CLASS_NAME = "javax.ws.rs.Path";
+
+ /**
+ * The annotation name of @HttpMethod
+ */
+ public static final String HTTP_METHOD_ANNOTATION_CLASS_NAME = "javax.ws.rs.HttpMethod";
+
+ /**
+ * The annotation class name of @Produces
+ */
+ public static final String PRODUCES_ANNOTATION_CLASS_NAME = "javax.ws.rs.Produces";
+
+ /**
+ * The annotation class name of @Consumes
+ */
+ public static final String CONSUMES_ANNOTATION_CLASS_NAME = "javax.ws.rs.Consumes";
+
+ @Override
+ public boolean supports(ProcessingEnvironment processingEnvironment, TypeElement serviceType) {
+ return isAnnotationPresent(serviceType, PATH_ANNOTATION_CLASS_NAME);
+ }
+
+ @Override
+ protected String getRequestPath(ProcessingEnvironment processingEnv, TypeElement serviceType, ExecutableElement method) {
+ String pathFromType = getPathValue(processingEnv, serviceType);
+ String pathFromMethod = getPathValue(method);
+ return buildPath(pathFromType, pathFromMethod);
+ }
+
+ @Override
+ protected String getRequestMethod(ProcessingEnvironment processingEnv, TypeElement serviceType, ExecutableElement method) {
+ AnnotationMirror annotation = findMetaAnnotation(method, HTTP_METHOD_ANNOTATION_CLASS_NAME);
+ return getValue(annotation);
+ }
+
+ @Override
+ protected void processProduces(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> produces) {
+ addAnnotationValues(method, PRODUCES_ANNOTATION_CLASS_NAME, produces);
+ }
+
+ @Override
+ protected void processConsumes(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> consumes) {
+ addAnnotationValues(method, CONSUMES_ANNOTATION_CLASS_NAME, consumes);
+ }
+
+
+ private void addAnnotationValues(Element element, String annotationAttributeName, Set<String> result) {
+ AnnotationMirror annotation = findAnnotation(element, annotationAttributeName);
+ String[] value = getValue(annotation);
+ if (value != null) {
+ Stream.of(value).forEach(result::add);
+ }
+ }
+
+ private String getPathValue(ProcessingEnvironment processingEnv, TypeElement serviceType) {
+ AnnotationMirror annotation = findAnnotation(serviceType, PATH_ANNOTATION_CLASS_NAME);
+ return getValue(annotation);
+ }
+
+ private String getPathValue(AnnotatedConstruct annotatedConstruct) {
+ AnnotationMirror annotation = getAnnotation(annotatedConstruct, PATH_ANNOTATION_CLASS_NAME);
+ return getValue(annotation);
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/MatrixParamParameterProcessor.java
similarity index 64%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/MatrixParamParameterProcessor.java
index 57832cc..026b648 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/MatrixParamParameterProcessor.java
@@ -14,24 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
/**
- * Object Utilities
+ * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @MatrixParam
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
+public class MatrixParamParameterProcessor extends ParamAnnotationParameterProcessor {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
+ @Override
+ public String getAnnotationType() {
+ return "javax.ws.rs.MatrixParam";
}
-
}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/ParamAnnotationParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/ParamAnnotationParameterProcessor.java
new file mode 100644
index 0000000..d615cdc
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/ParamAnnotationParameterProcessor.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 org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AbstractAnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.rest.RequestMetadata;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+/**
+ * The abstract {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @*Param
+ */
+public abstract class ParamAnnotationParameterProcessor extends AbstractAnnotatedMethodParameterProcessor {
+
+ protected void process(String name, String defaultValue, AnnotationMirror annotation, VariableElement parameter, int parameterIndex,
+ ExecutableElement method, RestMethodMetadata restMethodMetadata) {
+ RequestMetadata requestMetadata = restMethodMetadata.getRequest();
+ requestMetadata.addParam(name, defaultValue);
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/QueryParamParameterProcessor.java
similarity index 64%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/QueryParamParameterProcessor.java
index 57832cc..42e14ab 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/jaxrs/QueryParamParameterProcessor.java
@@ -14,24 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
/**
- * Object Utilities
+ * The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @QueryParam
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
+public class QueryParamParameterProcessor extends ParamAnnotationParameterProcessor {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
+ @Override
+ public String getAnnotationType() {
+ return "javax.ws.rs.QueryParam";
}
-
}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/AbstractRequestAnnotationParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/AbstractRequestAnnotationParameterProcessor.java
new file mode 100644
index 0000000..1fa5285
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/AbstractRequestAnnotationParameterProcessor.java
@@ -0,0 +1,69 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.springmvc;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AbstractAnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getAttribute;
+
+/**
+ * The abstract {@link AnnotatedMethodParameterProcessor} implementation for Spring Web MVC's @Request*
+ */
+public abstract class AbstractRequestAnnotationParameterProcessor extends AbstractAnnotatedMethodParameterProcessor {
+
+
+ protected abstract void process(String name, String defaultValue, AnnotationMirror annotation,
+ VariableElement parameter, int parameterIndex,
+ ExecutableElement method,
+ RestMethodMetadata restMethodMetadata);
+
+ @Override
+ protected String getAnnotationValue(AnnotationMirror annotation, VariableElement parameter, int parameterIndex) {
+ // try to get "value" attribute first
+ String name = super.getAnnotationValue(annotation, parameter, parameterIndex);
+
+ // try to get "name" attribute if required
+ if (isEmpty(name)) {
+ name = getAttribute(annotation, "name");
+ }
+
+ // finally , try to the name of parameter
+ if (isEmpty(name)) {
+ name = parameter.getSimpleName().toString();
+ }
+
+ return name;
+ }
+
+ protected String getDefaultValue(AnnotationMirror annotation, VariableElement parameter, int parameterIndex) {
+ String defaultValue = getAttribute(annotation, "defaultValue");
+ if (isEmpty(defaultValue)) {
+ defaultValue = super.getDefaultValue(annotation, parameter, parameterIndex);
+ }
+ return defaultValue;
+ }
+
+ protected boolean isEmpty(String str) {
+ return str == null || str.isEmpty();
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/RequestHeaderParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/RequestHeaderParameterProcessor.java
new file mode 100644
index 0000000..94929bc
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/RequestHeaderParameterProcessor.java
@@ -0,0 +1,41 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.springmvc;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+/**
+ * The {@link AnnotatedMethodParameterProcessor} implementation for Spring Web MVC's @RequestHeader
+ */
+public class RequestHeaderParameterProcessor extends AbstractRequestAnnotationParameterProcessor {
+
+ @Override
+ public String getAnnotationType() {
+ return "org.springframework.web.bind.annotation.RequestHeader";
+ }
+
+ @Override
+ protected void process(String name, String defaultValue, AnnotationMirror annotation, VariableElement parameter, int parameterIndex, ExecutableElement method, RestMethodMetadata restMethodMetadata) {
+ restMethodMetadata.getRequest().addHeader(name, defaultValue);
+ }
+
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/RequestParamParameterProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/RequestParamParameterProcessor.java
new file mode 100644
index 0000000..c2e3177
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/RequestParamParameterProcessor.java
@@ -0,0 +1,44 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.springmvc;
+
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
+import org.apache.dubbo.metadata.rest.RestMethodMetadata;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.VariableElement;
+
+/**
+ * The {@link AnnotatedMethodParameterProcessor} implementation for Spring Web MVC's @RequestParam
+ */
+@SPI
+public class RequestParamParameterProcessor extends AbstractRequestAnnotationParameterProcessor {
+
+ @Override
+ public String getAnnotationType() {
+ return "org.springframework.web.bind.annotation.RequestParam";
+ }
+
+ @Override
+ protected void process(String name, String defaultValue, AnnotationMirror annotation,
+ VariableElement parameter, int parameterIndex,
+ ExecutableElement method, RestMethodMetadata restMethodMetadata) {
+ restMethodMetadata.getRequest().addParam(name, defaultValue);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/SpringMvcServiceRestMetadataProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/SpringMvcServiceRestMetadataProcessor.java
new file mode 100644
index 0000000..b9f7009
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/springmvc/SpringMvcServiceRestMetadataProcessor.java
@@ -0,0 +1,157 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.rest.springmvc;
+
+import org.apache.dubbo.metadata.annotation.processing.rest.AbstractServiceRestMetadataProcessor;
+import org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataProcessor;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import java.lang.reflect.Array;
+import java.util.Set;
+
+import static java.lang.String.valueOf;
+import static java.lang.reflect.Array.getLength;
+import static java.util.stream.Stream.of;
+import static org.apache.dubbo.common.function.Streams.filterFirst;
+import static org.apache.dubbo.common.utils.ArrayUtils.isEmpty;
+import static org.apache.dubbo.common.utils.ArrayUtils.isNotEmpty;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.findAnnotation;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.findMetaAnnotation;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getAllAnnotations;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getAttribute;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.isAnnotationPresent;
+import static org.apache.dubbo.metadata.util.HttpUtils.buildPath;
+
+/**
+ * {@link ServiceRestMetadataProcessor}
+ *
+ * @since 2.7.5
+ */
+public class SpringMvcServiceRestMetadataProcessor extends AbstractServiceRestMetadataProcessor {
+
+ private static final int FIRST_ELEMENT_INDEX = 0;
+
+ public static final String CONTROLLER_ANNOTATION_CLASS_NAME = "org.springframework.stereotype.Controller";
+
+ public static final String REQUEST_MAPPING_ANNOTATION_CLASS_NAME = "org.springframework.web.bind.annotation.RequestMapping";
+
+ @Override
+ public boolean supports(ProcessingEnvironment processingEnvironment, TypeElement serviceType) {
+ return isAnnotationPresent(serviceType, CONTROLLER_ANNOTATION_CLASS_NAME);
+ }
+
+ @Override
+ protected String getRequestPath(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method) {
+
+ String requestPathFromType = getRequestPath(serviceType);
+
+ String requestPathFromMethod = getRequestPath(method);
+
+ return buildPath(requestPathFromType, requestPathFromMethod);
+ }
+
+
+ @Override
+ protected String getRequestMethod(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method) {
+
+ AnnotationMirror requestMapping = getRequestMapping(method);
+
+ // httpMethod is an array of RequestMethod
+ Object httpMethod = getAttribute(requestMapping, "method");
+
+ if (httpMethod == null || getLength(httpMethod) < 1) {
+ return null;
+ }
+
+ // TODO Is is required to support more request methods?
+ return valueOf(Array.get(httpMethod, FIRST_ELEMENT_INDEX));
+ }
+
+ private AnnotationMirror getRequestMapping(Element element) {
+ // try "@RequestMapping" first
+ AnnotationMirror requestMapping = findAnnotation(element, REQUEST_MAPPING_ANNOTATION_CLASS_NAME);
+ // try the annotation meta-annotated later
+ if (requestMapping == null) {
+ requestMapping = findMetaAnnotation(element, REQUEST_MAPPING_ANNOTATION_CLASS_NAME);
+ }
+ return requestMapping;
+ }
+
+ @Override
+ protected void processProduces(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> produces) {
+ addMediaTypes(method, "produces", produces);
+ }
+
+ @Override
+ protected void processConsumes(ProcessingEnvironment processingEnv, TypeElement serviceType,
+ ExecutableElement method, Set<String> consumes) {
+ addMediaTypes(method, "consumes", consumes);
+ }
+
+ private void addMediaTypes(ExecutableElement method, String annotationAttributeName, Set<String> mediaTypesSet) {
+
+ AnnotationMirror mappingAnnotation = getMappingAnnotation(method);
+
+ String[] mediaTypes = getAttribute(mappingAnnotation, annotationAttributeName);
+
+ if (isNotEmpty(mediaTypes)) {
+ of(mediaTypes).forEach(mediaTypesSet::add);
+ }
+ }
+
+ private AnnotationMirror getMappingAnnotation(Element element) {
+ return computeIfAbsent(valueOf(element), key ->
+ filterFirst(getAllAnnotations(element), annotation -> {
+ DeclaredType annotationType = annotation.getAnnotationType();
+ // try "@RequestMapping" first
+ if (REQUEST_MAPPING_ANNOTATION_CLASS_NAME.equals(annotationType.toString())) {
+ return true;
+ }
+ // try meta annotation
+ return isAnnotationPresent(annotationType.asElement(), REQUEST_MAPPING_ANNOTATION_CLASS_NAME);
+ })
+ );
+ }
+
+ private String getRequestPath(Element element) {
+ AnnotationMirror mappingAnnotation = getMappingAnnotation(element);
+ return getRequestPath(mappingAnnotation);
+ }
+
+ private String getRequestPath(AnnotationMirror mappingAnnotation) {
+ // try "value" first
+ String[] value = getAttribute(mappingAnnotation, "value");
+
+ if (isEmpty(value)) { // try "path" later
+ value = getAttribute(mappingAnnotation, "path");
+ }
+
+ if (isEmpty(value)) {
+ return "";
+ }
+ // TODO Is is required to support more request paths?
+ return value[FIRST_ELEMENT_INDEX];
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/AnnotationUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/AnnotationUtils.java
new file mode 100644
index 0000000..ac3877d
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/AnnotationUtils.java
@@ -0,0 +1,233 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.util;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.AnnotatedConstruct;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.type.ArrayType;
+import javax.lang.model.type.TypeMirror;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Array;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static java.lang.Enum.valueOf;
+import static java.util.Collections.emptyList;
+import static org.apache.dubbo.common.function.Predicates.EMPTY_ARRAY;
+import static org.apache.dubbo.common.function.Streams.filterAll;
+import static org.apache.dubbo.common.function.Streams.filterFirst;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getType;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isSameType;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isTypeElement;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofTypeElement;
+
+/**
+ * The utilities class for annotation in the package "javax.lang.model.*"
+ *
+ * @since 2.7.5
+ */
+public interface AnnotationUtils {
+
+ static AnnotationMirror getAnnotation(AnnotatedConstruct annotatedConstruct,
+ Class<? extends Annotation> annotationClass) {
+ return annotationClass == null ?
+ null :
+ getAnnotation(annotatedConstruct, annotationClass.getTypeName());
+ }
+
+ static AnnotationMirror getAnnotation(AnnotatedConstruct annotatedConstruct, CharSequence annotationClassName) {
+ List<AnnotationMirror> annotations = getAnnotations(annotatedConstruct, annotationClassName);
+ return annotations.isEmpty() ? null : annotations.get(0);
+ }
+
+ static List<AnnotationMirror> getAnnotations(AnnotatedConstruct annotatedConstruct, Class<? extends Annotation> annotationClass) {
+ return annotationClass == null ?
+ emptyList() :
+ getAnnotations(annotatedConstruct, annotationClass.getTypeName());
+ }
+
+ static List<AnnotationMirror> getAnnotations(AnnotatedConstruct annotatedConstruct,
+ CharSequence annotationClassName) {
+ return getAnnotations(annotatedConstruct,
+ annotation -> isSameType(annotation.getAnnotationType(), annotationClassName));
+ }
+
+ static List<AnnotationMirror> getAnnotations(AnnotatedConstruct annotatedConstruct) {
+ return getAnnotations(annotatedConstruct, EMPTY_ARRAY);
+ }
+
+ static List<AnnotationMirror> getAnnotations(AnnotatedConstruct annotatedConstruct,
+ Predicate<AnnotationMirror>... annotationFilters) {
+
+ AnnotatedConstruct actualAnnotatedConstruct = annotatedConstruct;
+
+ if (annotatedConstruct instanceof TypeMirror) {
+ actualAnnotatedConstruct = ofTypeElement((TypeMirror) actualAnnotatedConstruct);
+ }
+
+ return actualAnnotatedConstruct == null ?
+ emptyList() :
+ filterAll((List<AnnotationMirror>) actualAnnotatedConstruct.getAnnotationMirrors(), annotationFilters);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(TypeMirror type) {
+ return getAllAnnotations(ofTypeElement(type));
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(Element element) {
+ return getAllAnnotations(element, EMPTY_ARRAY);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(TypeMirror type, Class<? extends Annotation> annotationClass) {
+ return getAllAnnotations(ofTypeElement(type), annotationClass);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(Element element, Class<? extends Annotation> annotationClass) {
+ return element == null || annotationClass == null ?
+ emptyList() :
+ getAllAnnotations(element, annotationClass.getTypeName());
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(TypeMirror type, CharSequence annotationClassName) {
+ return getAllAnnotations(ofTypeElement(type), annotationClassName);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(Element element, CharSequence annotationClassName) {
+ return getAllAnnotations(element, annotation -> isSameType(annotation.getAnnotationType(), annotationClassName));
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(TypeMirror type, Predicate<AnnotationMirror>... annotationFilters) {
+ return getAllAnnotations(ofTypeElement(type), annotationFilters);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(Element element, Predicate<AnnotationMirror>... annotationFilters) {
+
+ List<AnnotationMirror> allAnnotations = isTypeElement(element) ?
+ getHierarchicalTypes(ofTypeElement(element))
+ .stream()
+ .map(AnnotationUtils::getAnnotations)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList()) :
+ element == null ? emptyList() : (List<AnnotationMirror>) element.getAnnotationMirrors();
+
+ return filterAll(allAnnotations, annotationFilters);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(ProcessingEnvironment processingEnv, Type annotatedType) {
+ return getAllAnnotations(processingEnv, annotatedType, EMPTY_ARRAY);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(ProcessingEnvironment processingEnv, Type annotatedType,
+ Predicate<AnnotationMirror>... annotationFilters) {
+ return annotatedType == null ?
+ emptyList() :
+ getAllAnnotations(processingEnv, annotatedType.getTypeName(), annotationFilters);
+ }
+
+ static List<AnnotationMirror> getAllAnnotations(ProcessingEnvironment processingEnv, CharSequence annotatedTypeName,
+ Predicate<AnnotationMirror>... annotationFilters) {
+ return getAllAnnotations(getType(processingEnv, annotatedTypeName), annotationFilters);
+ }
+
+ static AnnotationMirror findAnnotation(TypeMirror type, Class<? extends Annotation> annotationClass) {
+ return annotationClass == null ? null : findAnnotation(type, annotationClass.getTypeName());
+ }
+
+ static AnnotationMirror findAnnotation(TypeMirror type, CharSequence annotationClassName) {
+ return findAnnotation(ofTypeElement(type), annotationClassName);
+ }
+
+ static AnnotationMirror findAnnotation(Element element, Class<? extends Annotation> annotationClass) {
+ return annotationClass == null ? null : findAnnotation(element, annotationClass.getTypeName());
+ }
+
+ static AnnotationMirror findAnnotation(Element element, CharSequence annotationClassName) {
+ return filterFirst(getAllAnnotations(element, annotation -> isSameType(annotation.getAnnotationType(), annotationClassName)));
+ }
+
+ static AnnotationMirror findMetaAnnotation(Element annotatedConstruct, CharSequence metaAnnotationClassName) {
+ return annotatedConstruct == null ?
+ null :
+ getAnnotations(annotatedConstruct)
+ .stream()
+ .map(annotation -> findAnnotation(annotation.getAnnotationType(), metaAnnotationClassName))
+ .filter(Objects::nonNull)
+ .findFirst()
+ .orElse(null);
+ }
+
+ static boolean isAnnotationPresent(Element element, CharSequence annotationClassName) {
+ return findAnnotation(element, annotationClassName) != null ||
+ findMetaAnnotation(element, annotationClassName) != null;
+ }
+
+ static <T> T getAttribute(AnnotationMirror annotation, String attributeName) {
+ return annotation == null ? null : getAttribute(annotation.getElementValues(), attributeName);
+ }
+
+ static <T> T getAttribute(Map<? extends ExecutableElement, ? extends AnnotationValue> attributesMap,
+ String attributeName) {
+ T annotationValue = null;
+ for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : attributesMap.entrySet()) {
+ ExecutableElement attributeMethod = entry.getKey();
+ if (Objects.equals(attributeName, attributeMethod.getSimpleName().toString())) {
+ TypeMirror attributeType = attributeMethod.getReturnType();
+ AnnotationValue value = entry.getValue();
+ if (attributeType instanceof ArrayType) { // array-typed attribute values
+ ArrayType arrayType = (ArrayType) attributeType;
+ String componentType = arrayType.getComponentType().toString();
+ ClassLoader classLoader = AnnotationUtils.class.getClassLoader();
+ List<AnnotationValue> values = (List<AnnotationValue>) value.getValue();
+ int size = values.size();
+ try {
+ Class componentClass = classLoader.loadClass(componentType);
+ boolean isEnum = componentClass.isEnum();
+ Object array = Array.newInstance(componentClass, values.size());
+ for (int i = 0; i < size; i++) {
+ Object element = values.get(i).getValue();
+ if (isEnum) {
+ element = valueOf(componentClass, element.toString());
+ }
+ Array.set(array, i, element);
+ }
+ annotationValue = (T) array;
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ } else {
+ annotationValue = (T) value.getValue();
+ }
+ break;
+ }
+ }
+ return annotationValue;
+ }
+
+ static <T> T getValue(AnnotationMirror annotation) {
+ return (T) getAttribute(annotation, "value");
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/FieldUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/FieldUtils.java
new file mode 100644
index 0000000..b6c7346
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/FieldUtils.java
@@ -0,0 +1,146 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.util;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static java.util.Collections.emptyList;
+import static javax.lang.model.element.ElementKind.ENUM_CONSTANT;
+import static javax.lang.model.element.ElementKind.FIELD;
+import static javax.lang.model.element.Modifier.STATIC;
+import static javax.lang.model.util.ElementFilter.fieldsIn;
+import static org.apache.dubbo.common.function.Predicates.EMPTY_ARRAY;
+import static org.apache.dubbo.common.function.Streams.filterAll;
+import static org.apache.dubbo.common.function.Streams.filterFirst;
+import static org.apache.dubbo.metadata.annotation.processing.util.MemberUtils.getDeclaredMembers;
+import static org.apache.dubbo.metadata.annotation.processing.util.MemberUtils.hasModifiers;
+import static org.apache.dubbo.metadata.annotation.processing.util.MemberUtils.matches;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.isEnumType;
+
+/**
+ * The utilities class for the field in the package "javax.lang.model."
+ *
+ * @since 2.7.5
+ */
+public interface FieldUtils {
+
+ static List<VariableElement> getDeclaredFields(Element element, Predicate<VariableElement>... fieldFilters) {
+ return element == null ? emptyList() : getDeclaredFields(element.asType(), fieldFilters);
+ }
+
+ static List<VariableElement> getDeclaredFields(Element element) {
+ return getDeclaredFields(element, EMPTY_ARRAY);
+ }
+
+ static List<VariableElement> getDeclaredFields(TypeMirror type, Predicate<VariableElement>... fieldFilters) {
+ return filterAll(fieldsIn(getDeclaredMembers(type)), fieldFilters);
+ }
+
+ static List<VariableElement> getDeclaredFields(TypeMirror type) {
+ return getDeclaredFields(type, EMPTY_ARRAY);
+ }
+
+ static List<VariableElement> getAllDeclaredFields(Element element, Predicate<VariableElement>... fieldFilters) {
+ return element == null ? emptyList() : getAllDeclaredFields(element.asType(), fieldFilters);
+ }
+
+ static List<VariableElement> getAllDeclaredFields(Element element) {
+ return getAllDeclaredFields(element, EMPTY_ARRAY);
+ }
+
+ static List<VariableElement> getAllDeclaredFields(TypeMirror type, Predicate<VariableElement>... fieldFilters) {
+ return getHierarchicalTypes(type)
+ .stream()
+ .map(t -> getDeclaredFields(t, fieldFilters))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ static List<VariableElement> getAllDeclaredFields(TypeMirror type) {
+ return getAllDeclaredFields(type, EMPTY_ARRAY);
+ }
+
+ static VariableElement getDeclaredField(Element element, String fieldName) {
+ return element == null ? null : getDeclaredField(element.asType(), fieldName);
+ }
+
+ static VariableElement getDeclaredField(TypeMirror type, String fieldName) {
+ return filterFirst(getDeclaredFields(type, field -> fieldName.equals(field.getSimpleName().toString())));
+ }
+
+ static VariableElement findField(Element element, String fieldName) {
+ return element == null ? null : findField(element.asType(), fieldName);
+ }
+
+ static VariableElement findField(TypeMirror type, String fieldName) {
+ return filterFirst(getAllDeclaredFields(type, field -> equals(field, fieldName)));
+ }
+
+ /**
+ * is Enum's member field or not
+ *
+ * @param field {@link VariableElement} must be public static final fields
+ * @return if field is public static final, return <code>true</code>, or <code>false</code>
+ */
+ static boolean isEnumMemberField(VariableElement field) {
+ if (field == null || !isEnumType(field.getEnclosingElement())) {
+ return false;
+ }
+ return ENUM_CONSTANT.equals(field.getKind());
+ }
+
+ static boolean isNonStaticField(VariableElement field) {
+ return isField(field) && !hasModifiers(field, STATIC);
+ }
+
+ static boolean isField(VariableElement field) {
+ return matches(field, FIELD) || isEnumMemberField(field);
+ }
+
+ static boolean isField(VariableElement field, Modifier... modifiers) {
+ return isField(field) && hasModifiers(field, modifiers);
+ }
+
+ static List<VariableElement> getNonStaticFields(TypeMirror type) {
+ return getDeclaredFields(type, FieldUtils::isNonStaticField);
+ }
+
+ static List<VariableElement> getNonStaticFields(Element element) {
+ return element == null ? emptyList() : getNonStaticFields(element.asType());
+ }
+
+ static List<VariableElement> getAllNonStaticFields(TypeMirror type) {
+ return getAllDeclaredFields(type, FieldUtils::isNonStaticField);
+ }
+
+ static List<VariableElement> getAllNonStaticFields(Element element) {
+ return element == null ? emptyList() : getAllNonStaticFields(element.asType());
+ }
+
+ static boolean equals(VariableElement field, CharSequence fieldName) {
+ return field != null && fieldName != null && field.getSimpleName().toString().equals(fieldName.toString());
+ }
+
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/LoggerUtils.java
similarity index 56%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/LoggerUtils.java
index 57832cc..f43ffd9 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/LoggerUtils.java
@@ -14,24 +14,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.util;
+
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import static java.lang.String.format;
/**
- * Object Utilities
+ * Logger Utils
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
+public interface LoggerUtils {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
+ Logger LOGGER = LoggerFactory.getLogger("dubbo-metadata-processor");
+
+ static void info(String format, Object... args) {
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info(format(format, args));
+ }
}
+ static void warn(String format, Object... args) {
+ if (LOGGER.isWarnEnabled()) {
+ LOGGER.warn(format(format, args));
+ }
+ }
}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MemberUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MemberUtils.java
new file mode 100644
index 0000000..fc617a1
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MemberUtils.java
@@ -0,0 +1,94 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.util;
+
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.TypeMirror;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static java.util.Collections.emptyList;
+import static javax.lang.model.element.Modifier.PUBLIC;
+import static javax.lang.model.element.Modifier.STATIC;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofTypeElement;
+
+/**
+ * The utilities class for the members in the package "javax.lang.model.", such as "field", "method", "constructor"
+ *
+ * @since 2.7.5
+ */
+public interface MemberUtils {
+
+ static boolean matches(Element member, ElementKind kind) {
+ return member == null || kind == null ? false : kind.equals(member.getKind());
+ }
+
+ static boolean isPublicNonStatic(Element member) {
+ return hasModifiers(member, PUBLIC) && !hasModifiers(member, STATIC);
+ }
+
+ static boolean hasModifiers(Element member, Modifier... modifiers) {
+ if (member == null || modifiers == null) {
+ return false;
+ }
+ Set<Modifier> actualModifiers = member.getModifiers();
+ for (Modifier modifier : modifiers) {
+ if (!actualModifiers.contains(modifier)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ static List<? extends Element> getDeclaredMembers(TypeMirror type) {
+ TypeElement element = ofTypeElement(type);
+ return element == null ? emptyList() : element.getEnclosedElements();
+ }
+
+ static List<? extends Element> getAllDeclaredMembers(TypeMirror type) {
+ return getHierarchicalTypes(type)
+ .stream()
+ .map(MemberUtils::getDeclaredMembers)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ static boolean matchParameterTypes(List<? extends VariableElement> parameters, CharSequence... parameterTypes) {
+
+ int size = parameters.size();
+
+ if (size != parameterTypes.length) {
+ return false;
+ }
+
+ for (int i = 0; i < size; i++) {
+ VariableElement parameter = parameters.get(i);
+ if (!Objects.equals(parameter.asType().toString(), parameterTypes[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MethodUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MethodUtils.java
new file mode 100644
index 0000000..ab7c8c7
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/MethodUtils.java
@@ -0,0 +1,155 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.util;
+
+import javax.annotation.processing.ProcessingEnvironment;
+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 javax.lang.model.util.Elements;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static javax.lang.model.element.ElementKind.METHOD;
+import static javax.lang.model.util.ElementFilter.methodsIn;
+import static org.apache.dubbo.common.function.Predicates.EMPTY_ARRAY;
+import static org.apache.dubbo.common.function.Streams.filter;
+import static org.apache.dubbo.common.function.Streams.filterAll;
+import static org.apache.dubbo.common.function.Streams.filterFirst;
+import static org.apache.dubbo.metadata.annotation.processing.util.MemberUtils.getDeclaredMembers;
+import static org.apache.dubbo.metadata.annotation.processing.util.MemberUtils.isPublicNonStatic;
+import static org.apache.dubbo.metadata.annotation.processing.util.MemberUtils.matchParameterTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.getHierarchicalTypes;
+import static org.apache.dubbo.metadata.annotation.processing.util.TypeUtils.ofDeclaredType;
+
+/**
+ * The utilities class for method in the package "javax.lang.model."
+ *
+ * @since 2.7.5
+ */
+public interface MethodUtils {
+
+ static List<ExecutableElement> getDeclaredMethods(TypeElement type, Predicate<ExecutableElement>... methodFilters) {
+ return type == null ? emptyList() : getDeclaredMethods(type.asType(), methodFilters);
+ }
+
+ static List<ExecutableElement> getDeclaredMethods(TypeMirror type, Predicate<ExecutableElement>... methodFilters) {
+ return filterAll(methodsIn(getDeclaredMembers(type)), methodFilters);
+ }
+
+ static List<ExecutableElement> getAllDeclaredMethods(TypeElement type, Predicate<ExecutableElement>... methodFilters) {
+ return type == null ? emptyList() : getAllDeclaredMethods(type.asType(), methodFilters);
+ }
+
+ static List<ExecutableElement> getAllDeclaredMethods(TypeElement type) {
+ return getAllDeclaredMethods(type, EMPTY_ARRAY);
+ }
+
+ static List<ExecutableElement> getAllDeclaredMethods(TypeMirror type, Predicate<ExecutableElement>... methodFilters) {
+ return getHierarchicalTypes(type)
+ .stream()
+ .map(t -> getDeclaredMethods(t, methodFilters))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ static List<ExecutableElement> getAllDeclaredMethods(TypeMirror type) {
+ return getAllDeclaredMethods(type, EMPTY_ARRAY);
+ }
+
+ static List<ExecutableElement> getAllDeclaredMethods(TypeElement type, Type... excludedTypes) {
+ return type == null ? emptyList() : getAllDeclaredMethods(type.asType(), excludedTypes);
+ }
+
+ static List<ExecutableElement> getAllDeclaredMethods(TypeMirror type, Type... excludedTypes) {
+ return getHierarchicalTypes(type, excludedTypes)
+ .stream()
+ .map(t -> getDeclaredMethods(t))
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList());
+ }
+
+ static List<ExecutableElement> getPublicNonStaticMethods(TypeElement type, Type... excludedTypes) {
+ return getPublicNonStaticMethods(ofDeclaredType(type), excludedTypes);
+ }
+
+ static List<ExecutableElement> getPublicNonStaticMethods(TypeMirror type, Type... excludedTypes) {
+ return filter(getAllDeclaredMethods(type, excludedTypes), MethodUtils::isPublicNonStaticMethod);
+ }
+
+ static boolean isMethod(ExecutableElement method) {
+ return method == null ? false : METHOD.equals(method.getKind());
+ }
+
+ static boolean isPublicNonStaticMethod(ExecutableElement method) {
+ return isMethod(method) && isPublicNonStatic(method);
+ }
+
+ static ExecutableElement findMethod(TypeElement type, String methodName, Type oneParameterType, Type... otherParameterTypes) {
+ return type == null ? null : findMethod(type.asType(), methodName, oneParameterType, otherParameterTypes);
+ }
+
+ static ExecutableElement findMethod(TypeMirror type, String methodName, Type oneParameterType, Type... otherParameterTypes) {
+ List<Type> parameterTypes = new LinkedList<>();
+ parameterTypes.add(oneParameterType);
+ parameterTypes.addAll(asList(otherParameterTypes));
+ return findMethod(type, methodName, parameterTypes.stream().map(Type::getTypeName).toArray(String[]::new));
+ }
+
+ static ExecutableElement findMethod(TypeElement type, String methodName, CharSequence... parameterTypes) {
+ return type == null ? null : findMethod(type.asType(), methodName, parameterTypes);
+ }
+
+ static ExecutableElement findMethod(TypeMirror type, String methodName, CharSequence... parameterTypes) {
+ return filterFirst(getAllDeclaredMethods(type),
+ method -> methodName.equals(method.getSimpleName().toString()),
+ method -> matchParameterTypes(method.getParameters(), parameterTypes)
+ );
+ }
+
+ static ExecutableElement getOverrideMethod(ProcessingEnvironment processingEnv, TypeElement type,
+ ExecutableElement declaringMethod) {
+ Elements elements = processingEnv.getElementUtils();
+ return filterFirst(getAllDeclaredMethods(type), method -> elements.overrides(method, declaringMethod, type));
+ }
+
+
+ static String getMethodName(ExecutableElement method) {
+ return method == null ? null : method.getSimpleName().toString();
+ }
+
+ static String getReturnType(ExecutableElement method) {
+ return method == null ? null : method.getReturnType().toString();
+ }
+
+ static String[] getMethodParameterTypes(ExecutableElement method) {
+ return method == null ?
+ new String[0] :
+ method.getParameters()
+ .stream()
+ .map(Element::asType)
+ .map(TypeMirror::toString)
+ .toArray(String[]::new);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/ServiceAnnotationUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/ServiceAnnotationUtils.java
new file mode 100644
index 0000000..889e59f
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/ServiceAnnotationUtils.java
@@ -0,0 +1,121 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.util;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.TypeElement;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.lang.String.valueOf;
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableSet;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.getAttribute;
+import static org.apache.dubbo.metadata.annotation.processing.util.AnnotationUtils.isAnnotationPresent;
+
+/**
+ * The utilities class for @Service annotation
+ *
+ * @since 2.7.5
+ */
+public interface ServiceAnnotationUtils {
+
+ /**
+ * The class name of @Service
+ */
+ String SERVICE_ANNOTATION_TYPE = "org.apache.dubbo.config.annotation.Service";
+
+ /**
+ * The class name of the legacy @Service
+ */
+ @Deprecated
+ String LEGACY_SERVICE_ANNOTATION_TYPE = "com.alibaba.dubbo.config.annotation.Service";
+
+ /**
+ * the attribute name of @Service.interfaceClass()
+ */
+ String INTERFACE_CLASS_ATTRIBUTE_NAME = "interfaceClass";
+
+ /**
+ * the attribute name of @Service.interfaceName()
+ */
+ String INTERFACE_NAME_ATTRIBUTE_NAME = "interfaceName";
+
+ /**
+ * the attribute name of @Service.group()
+ */
+ String GROUP_ATTRIBUTE_NAME = "group";
+
+ /**
+ * the attribute name of @Service.version()
+ */
+ String VERSION_ATTRIBUTE_NAME = "version";
+
+ Set<String> SUPPORTED_ANNOTATION_TYPES = unmodifiableSet(new HashSet(asList(SERVICE_ANNOTATION_TYPE, LEGACY_SERVICE_ANNOTATION_TYPE)));
+
+ static boolean isServiceAnnotationPresent(TypeElement annotatedType) {
+ return isAnnotationPresent(annotatedType, SERVICE_ANNOTATION_TYPE) ||
+ isAnnotationPresent(annotatedType, LEGACY_SERVICE_ANNOTATION_TYPE);
+ }
+
+ static AnnotationMirror getAnnotation(TypeElement annotatedClass) {
+ return getAnnotation(annotatedClass.getAnnotationMirrors());
+ }
+
+ static AnnotationMirror getAnnotation(Iterable<? extends AnnotationMirror> annotationMirrors) {
+ AnnotationMirror matchedAnnotationMirror = null;
+ for (AnnotationMirror annotationMirror : annotationMirrors) {
+ String annotationType = annotationMirror.getAnnotationType().toString();
+ if (SERVICE_ANNOTATION_TYPE.equals(annotationType)) {
+ matchedAnnotationMirror = annotationMirror;
+ break;
+ } else if (LEGACY_SERVICE_ANNOTATION_TYPE.equals(annotationType)) {
+ matchedAnnotationMirror = annotationMirror;
+ }
+ }
+
+ if (matchedAnnotationMirror == null) {
+ throw new IllegalArgumentException("The annotated element must be implemented the interface "
+ + SERVICE_ANNOTATION_TYPE + " or " + LEGACY_SERVICE_ANNOTATION_TYPE);
+ }
+
+ return matchedAnnotationMirror;
+ }
+
+ static String resolveServiceInterfaceName(TypeElement annotatedClass, AnnotationMirror serviceAnnotation) {
+ Object interfaceClass = getAttribute(serviceAnnotation, INTERFACE_CLASS_ATTRIBUTE_NAME);
+
+ if (interfaceClass == null) { // try to find the "interfaceName" attribute
+ interfaceClass = getAttribute(serviceAnnotation, INTERFACE_NAME_ATTRIBUTE_NAME);
+ }
+
+ if (interfaceClass == null) {
+ // last, get the interface class from first one
+ interfaceClass = ((TypeElement) annotatedClass).getInterfaces().get(0);
+ }
+
+ return valueOf(interfaceClass);
+ }
+
+ static String getGroup(AnnotationMirror serviceAnnotation) {
+ return getAttribute(serviceAnnotation, GROUP_ATTRIBUTE_NAME);
+ }
+
+ static String getVersion(AnnotationMirror serviceAnnotation) {
+ return getAttribute(serviceAnnotation, VERSION_ATTRIBUTE_NAME);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/TypeUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/TypeUtils.java
new file mode 100644
index 0000000..3283d50
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/util/TypeUtils.java
@@ -0,0 +1,382 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.util;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.function.Predicate;
+
+import static java.lang.String.valueOf;
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptyList;
+import static java.util.Collections.emptySet;
+import static java.util.stream.Collectors.toSet;
+import static java.util.stream.Stream.of;
+import static java.util.stream.StreamSupport.stream;
+import static javax.lang.model.element.ElementKind.ANNOTATION_TYPE;
+import static javax.lang.model.element.ElementKind.CLASS;
+import static javax.lang.model.element.ElementKind.ENUM;
+import static javax.lang.model.element.ElementKind.INTERFACE;
+import static org.apache.dubbo.common.function.Predicates.EMPTY_ARRAY;
+import static org.apache.dubbo.common.function.Streams.filterAll;
+
+/**
+ * The utilities class for type in the package "javax.lang.model.*"
+ *
+ * @since 2.7.5
+ */
+public interface TypeUtils {
+
+ List<String> SIMPLE_TYPES = asList(
+ Void.class.getName(),
+ Boolean.class.getName(),
+ Character.class.getName(),
+ Byte.class.getName(),
+ Short.class.getName(),
+ Integer.class.getName(),
+ Long.class.getName(),
+ Float.class.getName(),
+ Double.class.getName(),
+ String.class.getName(),
+ BigDecimal.class.getName(),
+ BigInteger.class.getName(),
+ Date.class.getName()
+ );
+
+ static boolean isSimpleType(Element element) {
+ return element != null && isSimpleType(element.asType());
+ }
+
+ static boolean isSimpleType(TypeMirror type) {
+ return type != null && SIMPLE_TYPES.contains(type.toString());
+ }
+
+ static boolean isSameType(TypeMirror type, CharSequence typeName) {
+ if (type == null || typeName == null) {
+ return false;
+ }
+ return Objects.equals(valueOf(type), valueOf(typeName));
+ }
+
+ static boolean isSameType(TypeMirror typeMirror, Type type) {
+ return type != null && isSameType(typeMirror, type.getTypeName());
+ }
+
+ static boolean isArrayType(TypeMirror type) {
+ return type != null && TypeKind.ARRAY.equals(type.getKind());
+ }
+
+ static boolean isArrayType(Element element) {
+ return element != null && isArrayType(element.asType());
+ }
+
+ static boolean isEnumType(TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ return declaredType != null && ENUM.equals(declaredType.asElement().getKind());
+ }
+
+ static boolean isEnumType(Element element) {
+ return element != null && isEnumType(element.asType());
+ }
+
+ static boolean isClassType(TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ return declaredType != null && isClassType(declaredType.asElement());
+ }
+
+ static boolean isClassType(Element element) {
+ return element != null && CLASS.equals(element.getKind());
+ }
+
+ static boolean isPrimitiveType(TypeMirror type) {
+ return type != null && type.getKind().isPrimitive();
+ }
+
+ static boolean isPrimitiveType(Element element) {
+ return element != null && isPrimitiveType(element.asType());
+ }
+
+ static boolean isInterfaceType(TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ return declaredType != null && isInterfaceType(declaredType.asElement());
+ }
+
+ static boolean isInterfaceType(Element element) {
+ return element != null && INTERFACE.equals(element.getKind());
+ }
+
+ static boolean isAnnotationType(TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ return declaredType != null && isAnnotationType(declaredType.asElement());
+ }
+
+ static boolean isAnnotationType(Element element) {
+ return element != null && ANNOTATION_TYPE.equals(element.getKind());
+ }
+
+ static Set<TypeElement> getHierarchicalTypes(TypeElement type) {
+ return getHierarchicalTypes(type, true, true, true);
+ }
+
+ static Set<DeclaredType> getHierarchicalTypes(TypeMirror type) {
+ return getHierarchicalTypes(type, EMPTY_ARRAY);
+ }
+
+ static Set<DeclaredType> getHierarchicalTypes(TypeMirror type, Predicate<DeclaredType>... typeFilters) {
+ return filterAll(ofDeclaredTypes(getHierarchicalTypes(ofTypeElement(type))), typeFilters);
+ }
+
+ static Set<DeclaredType> getHierarchicalTypes(TypeMirror type, Type... excludedTypes) {
+ return getHierarchicalTypes(type, of(excludedTypes).map(Type::getTypeName).toArray(String[]::new));
+ }
+
+ static Set<DeclaredType> getHierarchicalTypes(TypeMirror type, CharSequence... excludedTypeNames) {
+ Set<String> typeNames = of(excludedTypeNames).map(CharSequence::toString).collect(toSet());
+ return getHierarchicalTypes(type, t -> !typeNames.contains(t.toString()));
+ }
+
+ static Set<TypeElement> getHierarchicalTypes(TypeElement type,
+ boolean includeSelf,
+ boolean includeSuperTypes,
+ boolean includeSuperInterfaces,
+ Predicate<TypeElement>... typeFilters) {
+
+ if (type == null) {
+ return emptySet();
+ }
+
+ Set<TypeElement> hierarchicalTypes = new LinkedHashSet<>();
+
+ if (includeSelf) {
+ hierarchicalTypes.add(type);
+ }
+
+ if (includeSuperTypes) {
+ hierarchicalTypes.addAll(getAllSuperTypes(type));
+ }
+
+ if (includeSuperInterfaces) {
+ hierarchicalTypes.addAll(getAllInterfaces(type));
+ }
+
+ return filterAll(hierarchicalTypes, typeFilters);
+ }
+
+ static Set<DeclaredType> getHierarchicalTypes(TypeMirror type,
+ boolean includeSelf,
+ boolean includeSuperTypes,
+ boolean includeSuperInterfaces) {
+ return ofDeclaredTypes(getHierarchicalTypes(ofTypeElement(type),
+ includeSelf,
+ includeSuperTypes,
+ includeSuperInterfaces));
+ }
+
+ static List<TypeMirror> getInterfaces(TypeElement type, Predicate<TypeMirror>... interfaceFilters) {
+ return type == null ? emptyList() : filterAll((List<TypeMirror>) ofTypeElement(type).getInterfaces(), interfaceFilters);
+ }
+
+ static List<TypeMirror> getInterfaces(TypeMirror type, Predicate<TypeMirror>... interfaceFilters) {
+ return getInterfaces(ofTypeElement(type), interfaceFilters);
+ }
+
+ static Set<TypeElement> getAllInterfaces(TypeElement type, Predicate<TypeElement>... interfaceFilters) {
+ return type == null ? emptySet() : filterAll(ofTypeElements(getAllInterfaces(type.asType())), interfaceFilters);
+ }
+
+ static Set<? extends TypeMirror> getAllInterfaces(TypeMirror type, Predicate<TypeMirror>... interfaceFilters) {
+ if (type == null) {
+ return emptySet();
+ }
+ Set<TypeMirror> allInterfaces = new LinkedHashSet<>();
+ getInterfaces(type).forEach(i -> {
+ // Add current type's interfaces
+ allInterfaces.add(i);
+ // Add
+ allInterfaces.addAll(getAllInterfaces(i));
+ });
+ // Add all super types' interfaces
+ getAllSuperTypes(type).forEach(superType -> allInterfaces.addAll(getAllInterfaces(superType)));
+ return filterAll(allInterfaces, interfaceFilters);
+ }
+
+ static TypeElement getType(ProcessingEnvironment processingEnv, Type type) {
+ return type == null ? null : getType(processingEnv, type.getTypeName());
+ }
+
+ static TypeElement getType(ProcessingEnvironment processingEnv, TypeMirror type) {
+ return type == null ? null : getType(processingEnv, type.toString());
+ }
+
+ static TypeElement getType(ProcessingEnvironment processingEnv, CharSequence typeName) {
+ if (processingEnv == null || typeName == null) {
+ return null;
+ }
+ Elements elements = processingEnv.getElementUtils();
+ return elements.getTypeElement(typeName);
+ }
+
+ static TypeElement getSuperType(TypeElement type) {
+ return type == null ? null : ofTypeElement(type.getSuperclass());
+ }
+
+ static DeclaredType getSuperType(TypeMirror type) {
+ TypeElement superType = getSuperType(ofTypeElement(type));
+ return superType == null ? null : ofDeclaredType(superType.asType());
+ }
+
+ static Set<TypeElement> getAllSuperTypes(TypeElement type) {
+ return getAllSuperTypes(type, EMPTY_ARRAY);
+ }
+
+ static Set<TypeElement> getAllSuperTypes(TypeElement type, Predicate<TypeElement>... typeFilters) {
+ if (type == null) {
+ return emptySet();
+ }
+
+ Set<TypeElement> allSuperTypes = new LinkedHashSet<>();
+ TypeElement superType = getSuperType(type);
+ if (superType != null) {
+ // add super type
+ allSuperTypes.add(superType);
+ // add ancestors' types
+ allSuperTypes.addAll(getAllSuperTypes(superType));
+ }
+ return filterAll(allSuperTypes, typeFilters);
+ }
+
+ static Set<DeclaredType> getAllSuperTypes(TypeMirror type) {
+ return getAllSuperTypes(type, EMPTY_ARRAY);
+ }
+
+ static Set<DeclaredType> getAllSuperTypes(TypeMirror type, Predicate<DeclaredType>... typeFilters) {
+ return filterAll(ofDeclaredTypes(getAllSuperTypes(ofTypeElement(type))), typeFilters);
+ }
+
+ static boolean isDeclaredType(Element element) {
+ return element != null && isDeclaredType(element.asType());
+ }
+
+ static boolean isDeclaredType(TypeMirror type) {
+ return type instanceof DeclaredType;
+ }
+
+ static DeclaredType ofDeclaredType(Element element) {
+ return element == null ? null : ofDeclaredType(element.asType());
+ }
+
+ static DeclaredType ofDeclaredType(TypeMirror type) {
+ return isDeclaredType(type) ? DeclaredType.class.cast(type) : null;
+ }
+
+ static boolean isTypeElement(Element element) {
+ return element instanceof TypeElement;
+ }
+
+ static boolean isTypeElement(TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ return declaredType != null && isTypeElement(declaredType.asElement());
+ }
+
+ static TypeElement ofTypeElement(Element element) {
+ return isTypeElement(element) ? TypeElement.class.cast(element) : null;
+ }
+
+ static TypeElement ofTypeElement(TypeMirror type) {
+ DeclaredType declaredType = ofDeclaredType(type);
+ if (declaredType != null) {
+ return ofTypeElement(declaredType.asElement());
+ }
+ return null;
+ }
+
+ static Set<DeclaredType> ofDeclaredTypes(Iterable<? extends Element> elements) {
+ return elements == null ?
+ emptySet() :
+ stream(elements.spliterator(), false)
+ .map(TypeUtils::ofTypeElement)
+ .filter(Objects::nonNull)
+ .map(Element::asType)
+ .map(TypeUtils::ofDeclaredType)
+ .filter(Objects::nonNull)
+ .collect(LinkedHashSet::new, Set::add, Set::addAll);
+ }
+
+ static Set<TypeElement> ofTypeElements(Iterable<? extends TypeMirror> types) {
+ return types == null ?
+ emptySet() :
+ stream(types.spliterator(), false)
+ .map(TypeUtils::ofTypeElement)
+ .filter(Objects::nonNull)
+ .collect(LinkedHashSet::new, Set::add, Set::addAll);
+ }
+
+ static List<DeclaredType> listDeclaredTypes(Iterable<? extends Element> elements) {
+ return new ArrayList<>(ofDeclaredTypes(elements));
+ }
+
+ static List<TypeElement> listTypeElements(Iterable<? extends TypeMirror> types) {
+ return new ArrayList<>(ofTypeElements(types));
+ }
+
+ static URL getResource(ProcessingEnvironment processingEnv, Element type) {
+ return getResource(processingEnv, ofDeclaredType(type));
+ }
+
+ static URL getResource(ProcessingEnvironment processingEnv, TypeMirror type) {
+ return type == null ? null : getResource(processingEnv, type.toString());
+ }
+
+ static URL getResource(ProcessingEnvironment processingEnv, CharSequence type) {
+ String relativeName = getResourceName(type);
+ URL resource = null;
+ try {
+ if (relativeName != null) {
+ FileObject fileObject = processingEnv.getFiler().getResource(StandardLocation.CLASS_OUTPUT, "", relativeName);
+ resource = fileObject.toUri().toURL();
+ // try to open it
+ resource.getContent();
+ }
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ return resource;
+ }
+
+ static String getResourceName(CharSequence type) {
+ return type == null ? null : type.toString().replace('.', '/').concat(".class");
+ }
+}
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder
new file mode 100644
index 0000000..13e09b8
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder
@@ -0,0 +1,7 @@
+array = org.apache.dubbo.metadata.annotation.processing.builder.ArrayTypeDefinitionBuilder
+collection = org.apache.dubbo.metadata.annotation.processing.builder.CollectionTypeDefinitionBuilder
+enum = org.apache.dubbo.metadata.annotation.processing.builder.EnumTypeDefinitionBuilder
+general = org.apache.dubbo.metadata.annotation.processing.builder.GeneralTypeDefinitionBuilder
+map = org.apache.dubbo.metadata.annotation.processing.builder.MapTypeDefinitionBuilder
+primitive = org.apache.dubbo.metadata.annotation.processing.builder.PrimitiveTypeDefinitionBuilder
+simple = org.apache.dubbo.metadata.annotation.processing.builder.SimpleTypeDefinitionBuilder
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor
new file mode 100644
index 0000000..5f40699
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor
@@ -0,0 +1,10 @@
+# JAX-RS's implementations
+jaxrs.query-param = org.apache.dubbo.metadata.annotation.processing.rest.jaxrs.QueryParamParameterProcessor
+jaxrs.form-param = org.apache.dubbo.metadata.annotation.processing.rest.jaxrs.FormParamParameterProcessor
+jaxrs.matrix-param = org.apache.dubbo.metadata.annotation.processing.rest.jaxrs.MatrixParamParameterProcessor
+jaxrs.header-param = org.apache.dubbo.metadata.annotation.processing.rest.jaxrs.HeaderParamParameterProcessor
+jaxrs.default-value-param = org.apache.dubbo.metadata.annotation.processing.rest.jaxrs.DefaultValueParameterProcessor
+
+# Spring Web MVC's implementations
+springmvc.request-param = org.apache.dubbo.metadata.annotation.processing.rest.springmvc.RequestParamParameterProcessor
+springmvc.request-header = org.apache.dubbo.metadata.annotation.processing.rest.springmvc.RequestHeaderParameterProcessor
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataProcessor b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataProcessor
new file mode 100644
index 0000000..fb0bd98
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataProcessor
@@ -0,0 +1,3 @@
+# org.apache.dubbo.metadata.annotation.processing.rest.DefaultServiceRestMetadataProcessor
+jaxrs = org.apache.dubbo.metadata.annotation.processing.rest.jaxrs.JAXRSServiceRestMetadataProcessor
+springmvc = org.apache.dubbo.metadata.annotation.processing.rest.springmvc.SpringMvcServiceRestMetadataProcessor
\ No newline at end of file
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
new file mode 100644
index 0000000..6c5909c
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor
@@ -0,0 +1,2 @@
+org.apache.dubbo.metadata.annotation.processing.ServiceDefinitionMetadataAnnotationProcessor
+org.apache.dubbo.metadata.annotation.processing.rest.ServiceRestMetadataAnnotationProcessor
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java
new file mode 100644
index 0000000..0e5adf4
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/AbstractAnnotationProcessingTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing;
+
+import org.apache.dubbo.metadata.annotation.processing.util.TypeUtils;
+import org.apache.dubbo.metadata.tools.Compiler;
+import org.apache.dubbo.metadata.tools.TestProcessor;
+
+import org.junit.jupiter.api.BeforeEach;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+import javax.lang.model.util.Types;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Abstract {@link Annotation} Processing Test case
+ *
+ * @since 2.7.5
+ */
+public abstract class AbstractAnnotationProcessingTest {
+
+ protected ProcessingEnvironment processingEnv;
+
+ protected Elements elements;
+
+ protected Types types;
+
+ @BeforeEach
+ public final void init() throws IOException {
+ Set<Class<?>> classesToBeCompiled = new LinkedHashSet<>();
+ classesToBeCompiled.add(getClass());
+ addCompiledClasses(classesToBeCompiled);
+ TestProcessor testProcessor = new TestProcessor();
+ Compiler compiler = new Compiler();
+ compiler.processors(testProcessor);
+ compiler.compile(classesToBeCompiled.toArray(new Class[0]));
+ processingEnv = testProcessor.getProcessingEnvironment();
+ elements = processingEnv.getElementUtils();
+ types = processingEnv.getTypeUtils();
+ beforeEach();
+ }
+
+ protected abstract void addCompiledClasses(Set<Class<?>> classesToBeCompiled);
+
+ protected abstract void beforeEach();
+
+ protected TypeElement getType(Class<?> type) {
+ return TypeUtils.getType(processingEnv, type);
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..efab557
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ArrayTypeDefinitionBuilderTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.ArrayTypeModel;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import org.junit.jupiter.api.Test;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.stream.Stream;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link ArrayTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class ArrayTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private ArrayTypeDefinitionBuilder builder;
+
+ private TypeElement testType;
+
+ private VariableElement integersField;
+
+ private VariableElement stringsField;
+
+ private VariableElement primitiveTypeModelsField;
+
+ private VariableElement modelsField;
+
+ private VariableElement colorsField;
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(ArrayTypeModel.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ builder = new ArrayTypeDefinitionBuilder();
+ testType = getType(ArrayTypeModel.class);
+ integersField = findField(testType, "integers");
+ stringsField = findField(testType, "strings");
+ primitiveTypeModelsField = findField(testType, "primitiveTypeModels");
+ modelsField = findField(testType, "models");
+ colorsField = findField(testType, "colors");
+ }
+
+ @Test
+ public void testAccept() {
+ assertTrue(builder.accept(processingEnv, integersField.asType()));
+ assertTrue(builder.accept(processingEnv, stringsField.asType()));
+ assertTrue(builder.accept(processingEnv, primitiveTypeModelsField.asType()));
+ assertTrue(builder.accept(processingEnv, modelsField.asType()));
+ assertTrue(builder.accept(processingEnv, colorsField.asType()));
+ }
+
+ @Test
+ public void testBuild() {
+
+ buildAndAssertTypeDefinition(processingEnv, integersField, "int[]", "int", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, stringsField, "java.lang.String[]", "java.lang.String", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, primitiveTypeModelsField,
+ "org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel[]",
+ "org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, modelsField,
+ "org.apache.dubbo.metadata.annotation.processing.model.Model[]",
+ "org.apache.dubbo.metadata.annotation.processing.model.Model", builder, (def, subDef) -> {
+ TypeElement subType = elements.getTypeElement(subDef.getType());
+ assertEquals(ElementKind.CLASS, subType.getKind());
+ });
+
+ buildAndAssertTypeDefinition(processingEnv, colorsField,
+ "org.apache.dubbo.metadata.annotation.processing.model.Color[]",
+ "org.apache.dubbo.metadata.annotation.processing.model.Color", builder, (def, subDef) -> {
+ TypeElement subType = elements.getTypeElement(subDef.getType());
+ assertEquals(ElementKind.ENUM, subType.getKind());
+ });
+
+ }
+
+ static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field,
+ String expectedType, String compositeType, TypeDefinitionBuilder builder,
+ BiConsumer<TypeDefinition, TypeDefinition>... assertions) {
+ TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
+ TypeDefinition subTypeDefinition = typeDefinition.getItems().get(0);
+ assertEquals(expectedType, typeDefinition.getType());
+ assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
+ assertEquals(compositeType, subTypeDefinition.getType());
+// assertEquals(builder.getClass().getName(), typeDefinition.getTypeBuilderName());
+ Stream.of(assertions).forEach(assertion -> assertion.accept(typeDefinition, subTypeDefinition));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..7f1a2b2
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/CollectionTypeDefinitionBuilderTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.CollectionTypeModel;
+
+import org.junit.jupiter.api.Test;
+
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.util.Set;
+
+import static org.apache.dubbo.metadata.annotation.processing.builder.ArrayTypeDefinitionBuilderTest.buildAndAssertTypeDefinition;
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link CollectionTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class CollectionTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private CollectionTypeDefinitionBuilder builder;
+
+ private VariableElement stringsField;
+
+ private VariableElement colorsField;
+
+ private VariableElement primitiveTypeModelsField;
+
+ private VariableElement modelsField;
+
+ private VariableElement modelArraysField;
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(CollectionTypeModel.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ builder = new CollectionTypeDefinitionBuilder();
+ TypeElement testType = getType(CollectionTypeModel.class);
+ stringsField = findField(testType, "strings");
+ colorsField = findField(testType, "colors");
+ primitiveTypeModelsField = findField(testType, "primitiveTypeModels");
+ modelsField = findField(testType, "models");
+ modelArraysField = findField(testType, "modelArrays");
+
+ assertEquals("strings", stringsField.getSimpleName().toString());
+ assertEquals("colors", colorsField.getSimpleName().toString());
+ assertEquals("primitiveTypeModels", primitiveTypeModelsField.getSimpleName().toString());
+ assertEquals("models", modelsField.getSimpleName().toString());
+ assertEquals("modelArrays", modelArraysField.getSimpleName().toString());
+ }
+
+ @Test
+ public void testAccept() {
+ assertTrue(builder.accept(processingEnv, stringsField.asType()));
+ assertTrue(builder.accept(processingEnv, colorsField.asType()));
+ assertTrue(builder.accept(processingEnv, primitiveTypeModelsField.asType()));
+ assertTrue(builder.accept(processingEnv, modelsField.asType()));
+ assertTrue(builder.accept(processingEnv, modelArraysField.asType()));
+ }
+
+ @Test
+ public void testBuild() {
+
+ buildAndAssertTypeDefinition(processingEnv, stringsField, "java.util.Collection<java.lang.String>", "java.lang.String", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, colorsField, "java.util.List<org.apache.dubbo.metadata.annotation.processing.model.Color>",
+ "org.apache.dubbo.metadata.annotation.processing.model.Color", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, primitiveTypeModelsField,
+ "java.util.Queue<org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel>",
+ "org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, modelsField,
+ "java.util.Deque<org.apache.dubbo.metadata.annotation.processing.model.Model>",
+ "org.apache.dubbo.metadata.annotation.processing.model.Model", builder);
+
+ buildAndAssertTypeDefinition(processingEnv, modelArraysField,
+ "java.util.Set<org.apache.dubbo.metadata.annotation.processing.model.Model[]>",
+ "org.apache.dubbo.metadata.annotation.processing.model.Model[]", builder);
+
+
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..52f33aa
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/EnumTypeDefinitionBuilderTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.Color;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import org.junit.jupiter.api.Test;
+
+import javax.lang.model.element.TypeElement;
+import java.util.Set;
+
+import static java.util.Arrays.asList;
+import static org.apache.dubbo.metadata.annotation.processing.builder.TypeDefinitionBuilder.build;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link EnumTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class EnumTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private EnumTypeDefinitionBuilder builder;
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(Color.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ builder = new EnumTypeDefinitionBuilder();
+ }
+
+ @Test
+ public void testAccept() {
+ TypeElement typeElement = getType(Color.class);
+ assertTrue(builder.accept(processingEnv, typeElement.asType()));
+ }
+
+ @Test
+ public void testBuild() {
+ TypeElement typeElement = getType(Color.class);
+ TypeDefinition typeDefinition = build(processingEnv, typeElement);
+ assertEquals(Color.class.getName(), typeDefinition.getType());
+ assertEquals(asList("RED", "YELLOW", "BLUE"), typeDefinition.getEnums());
+// assertEquals(typeDefinition.getTypeBuilderName(), builder.getClass().getName());
+ }
+
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..8be38dc
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/GeneralTypeDefinitionBuilderTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.ArrayTypeModel;
+import org.apache.dubbo.metadata.annotation.processing.model.CollectionTypeModel;
+import org.apache.dubbo.metadata.annotation.processing.model.Color;
+import org.apache.dubbo.metadata.annotation.processing.model.Model;
+import org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel;
+import org.apache.dubbo.metadata.annotation.processing.model.SimpleTypeModel;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link GeneralTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class GeneralTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private GeneralTypeDefinitionBuilder builder;
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(Model.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ builder = new GeneralTypeDefinitionBuilder();
+ }
+
+ @Test
+ public void testAccept() {
+ assertTrue(builder.accept(processingEnv, getType(Model.class).asType()));
+ assertTrue(builder.accept(processingEnv, getType(PrimitiveTypeModel.class).asType()));
+ assertTrue(builder.accept(processingEnv, getType(SimpleTypeModel.class).asType()));
+ assertTrue(builder.accept(processingEnv, getType(ArrayTypeModel.class).asType()));
+ assertTrue(builder.accept(processingEnv, getType(CollectionTypeModel.class).asType()));
+ assertFalse(builder.accept(processingEnv, getType(Color.class).asType()));
+ }
+
+ @Test
+ public void testBuild() {
+
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..cc75c91
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/MapTypeDefinitionBuilderTest.java
@@ -0,0 +1,134 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.MapTypeModel;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import org.junit.jupiter.api.Test;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import java.util.stream.Stream;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link MapTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class MapTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private MapTypeDefinitionBuilder builder;
+
+ private VariableElement stringsField;
+
+ private VariableElement colorsField;
+
+ private VariableElement primitiveTypeModelsField;
+
+ private VariableElement modelsField;
+
+ private VariableElement modelArraysField;
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(MapTypeModel.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ builder = new MapTypeDefinitionBuilder();
+ TypeElement testType = getType(MapTypeModel.class);
+ stringsField = findField(testType, "strings");
+ colorsField = findField(testType, "colors");
+ primitiveTypeModelsField = findField(testType, "primitiveTypeModels");
+ modelsField = findField(testType, "models");
+ modelArraysField = findField(testType, "modelArrays");
+
+ assertEquals("strings", stringsField.getSimpleName().toString());
+ assertEquals("colors", colorsField.getSimpleName().toString());
+ assertEquals("primitiveTypeModels", primitiveTypeModelsField.getSimpleName().toString());
+ assertEquals("models", modelsField.getSimpleName().toString());
+ assertEquals("modelArrays", modelArraysField.getSimpleName().toString());
+ }
+
+ @Test
+ public void testAccept() {
+ assertTrue(builder.accept(processingEnv, stringsField.asType()));
+ assertTrue(builder.accept(processingEnv, colorsField.asType()));
+ assertTrue(builder.accept(processingEnv, primitiveTypeModelsField.asType()));
+ assertTrue(builder.accept(processingEnv, modelsField.asType()));
+ assertTrue(builder.accept(processingEnv, modelArraysField.asType()));
+ }
+
+ @Test
+ public void testBuild() {
+
+ buildAndAssertTypeDefinition(processingEnv, stringsField,
+ "java.util.Map<java.lang.String,java.lang.String>",
+ "java.lang.String",
+ "java.lang.String",
+ builder);
+
+ buildAndAssertTypeDefinition(processingEnv, colorsField,
+ "java.util.SortedMap<java.lang.String,org.apache.dubbo.metadata.annotation.processing.model.Color>",
+ "java.lang.String",
+ "org.apache.dubbo.metadata.annotation.processing.model.Color",
+ builder);
+
+ buildAndAssertTypeDefinition(processingEnv, primitiveTypeModelsField,
+ "java.util.NavigableMap<org.apache.dubbo.metadata.annotation.processing.model.Color,org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel>",
+ "org.apache.dubbo.metadata.annotation.processing.model.Color",
+ "org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel",
+ builder);
+
+ buildAndAssertTypeDefinition(processingEnv, modelsField,
+ "java.util.HashMap<java.lang.String,org.apache.dubbo.metadata.annotation.processing.model.Model>",
+ "java.lang.String",
+ "org.apache.dubbo.metadata.annotation.processing.model.Model",
+ builder);
+
+ buildAndAssertTypeDefinition(processingEnv, modelArraysField,
+ "java.util.TreeMap<org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel,org.apache.dubbo.metadata.annotation.processing.model.Model[]>",
+ "org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel",
+ "org.apache.dubbo.metadata.annotation.processing.model.Model[]",
+ builder);
+ }
+
+ static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field,
+ String expectedType, String keyType, String valueType,
+ TypeDefinitionBuilder builder,
+ BiConsumer<TypeDefinition, TypeDefinition>... assertions) {
+ TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
+ TypeDefinition keyTypeDefinition = typeDefinition.getItems().get(0);
+ TypeDefinition valueTypeDefinition = typeDefinition.getItems().get(1);
+ assertEquals(expectedType, typeDefinition.getType());
+ assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
+ assertEquals(keyType, keyTypeDefinition.getType());
+ assertEquals(valueType, valueTypeDefinition.getType());
+// assertEquals(builder.getClass().getName(), typeDefinition.getTypeBuilderName());
+ Stream.of(assertions).forEach(assertion -> assertion.accept(typeDefinition, keyTypeDefinition));
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..3b32173
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/PrimitiveTypeDefinitionBuilderTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.PrimitiveTypeModel;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import org.junit.jupiter.api.Test;
+
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.util.Set;
+
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * {@link PrimitiveTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class PrimitiveTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private PrimitiveTypeDefinitionBuilder builder;
+
+ private VariableElement zField;
+
+ private VariableElement bField;
+
+ private VariableElement cField;
+
+ private VariableElement sField;
+
+ private VariableElement iField;
+
+ private VariableElement lField;
+
+ private VariableElement fField;
+
+ private VariableElement dField;
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(PrimitiveTypeModel.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+
+ builder = new PrimitiveTypeDefinitionBuilder();
+
+ TypeElement testType = getType(PrimitiveTypeModel.class);
+
+ zField = findField(testType, "z");
+ bField = findField(testType, "b");
+ cField = findField(testType, "c");
+ sField = findField(testType, "s");
+ iField = findField(testType, "i");
+ lField = findField(testType, "l");
+ fField = findField(testType, "f");
+ dField = findField(testType, "d");
+
+ assertEquals("boolean", zField.asType().toString());
+ assertEquals("byte", bField.asType().toString());
+ assertEquals("char", cField.asType().toString());
+ assertEquals("short", sField.asType().toString());
+ assertEquals("int", iField.asType().toString());
+ assertEquals("long", lField.asType().toString());
+ assertEquals("float", fField.asType().toString());
+ assertEquals("double", dField.asType().toString());
+ }
+
+ @Test
+ public void testAccept() {
+ assertTrue(builder.accept(processingEnv, zField.asType()));
+ assertTrue(builder.accept(processingEnv, bField.asType()));
+ assertTrue(builder.accept(processingEnv, cField.asType()));
+ assertTrue(builder.accept(processingEnv, sField.asType()));
+ assertTrue(builder.accept(processingEnv, iField.asType()));
+ assertTrue(builder.accept(processingEnv, lField.asType()));
+ assertTrue(builder.accept(processingEnv, fField.asType()));
+ assertTrue(builder.accept(processingEnv, dField.asType()));
+ }
+
+ @Test
+ public void testBuild() {
+ buildAndAssertTypeDefinition(processingEnv, zField, builder);
+ buildAndAssertTypeDefinition(processingEnv, bField, builder);
+ buildAndAssertTypeDefinition(processingEnv, cField, builder);
+ buildAndAssertTypeDefinition(processingEnv, sField, builder);
+ buildAndAssertTypeDefinition(processingEnv, iField, builder);
+ buildAndAssertTypeDefinition(processingEnv, lField, builder);
+ buildAndAssertTypeDefinition(processingEnv, zField, builder);
+ buildAndAssertTypeDefinition(processingEnv, fField, builder);
+ buildAndAssertTypeDefinition(processingEnv, dField, builder);
+ }
+
+ static void buildAndAssertTypeDefinition(ProcessingEnvironment processingEnv, VariableElement field, TypeDefinitionBuilder builder) {
+ TypeDefinition typeDefinition = TypeDefinitionBuilder.build(processingEnv, field);
+ assertBasicTypeDefinition(typeDefinition, field.asType().toString(), builder);
+ assertEquals(field.getSimpleName().toString(), typeDefinition.get$ref());
+ }
+
+ static void assertBasicTypeDefinition(TypeDefinition typeDefinition, String type, TypeDefinitionBuilder builder) {
+ assertEquals(type, typeDefinition.getType());
+// assertEquals(builder.getClass().getName(), typeDefinition.getTypeBuilderName());
+ assertTrue(typeDefinition.getProperties().isEmpty());
+ assertTrue(typeDefinition.getItems().isEmpty());
+ assertTrue(typeDefinition.getEnums().isEmpty());
+ assertNull(typeDefinition.getId());
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.java
new file mode 100644
index 0000000..c891f87
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/ServiceDefinitionBuilderTest.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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
+import org.apache.dubbo.metadata.tools.TestServiceImpl;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+import static org.apache.dubbo.metadata.annotation.processing.builder.ServiceDefinitionBuilder.build;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+/**
+ * {@link ServiceDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class ServiceDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(TestServiceImpl.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ }
+
+ @Test
+ public void testBuild() {
+ ServiceDefinition serviceDefinition = build(processingEnv, getType(TestServiceImpl.class));
+ assertEquals(TestServiceImpl.class.getTypeName(), serviceDefinition.getCanonicalName());
+ assertEquals("org/apache/dubbo/metadata/tools/TestServiceImpl.class", serviceDefinition.getCodeSource());
+ // types
+ int i = 0;
+ assertEquals("org.apache.dubbo.metadata.tools.TestServiceImpl", serviceDefinition.getTypes().get(i++).getType());
+ assertEquals("org.apache.dubbo.metadata.tools.GenericTestService", serviceDefinition.getTypes().get(i++).getType());
+ assertEquals("org.apache.dubbo.metadata.tools.DefaultTestService", serviceDefinition.getTypes().get(i++).getType());
+ assertEquals("org.apache.dubbo.metadata.tools.TestService", serviceDefinition.getTypes().get(i++).getType());
+ assertEquals("java.lang.AutoCloseable", serviceDefinition.getTypes().get(i++).getType());
+ assertEquals("java.io.Serializable", serviceDefinition.getTypes().get(i++).getType());
+ assertEquals("java.util.EventListener", serviceDefinition.getTypes().get(i++).getType());
+ // methods
+ assertEquals(14, serviceDefinition.getMethods().size());
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilderTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilderTest.java
new file mode 100644
index 0000000..365ac56
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/builder/SimpleTypeDefinitionBuilderTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.builder;
+
+import org.apache.dubbo.metadata.annotation.processing.AbstractAnnotationProcessingTest;
+import org.apache.dubbo.metadata.annotation.processing.model.SimpleTypeModel;
+
+import org.junit.jupiter.api.Test;
+
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import java.util.Set;
+
+import static org.apache.dubbo.metadata.annotation.processing.builder.PrimitiveTypeDefinitionBuilderTest.buildAndAssertTypeDefinition;
+import static org.apache.dubbo.metadata.annotation.processing.util.FieldUtils.findField;
+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 SimpleTypeDefinitionBuilder} Test
+ *
+ * @since 2.7.5
+ */
+public class SimpleTypeDefinitionBuilderTest extends AbstractAnnotationProcessingTest {
+
+ private SimpleTypeDefinitionBuilder builder;
+
+ private VariableElement vField;
+
+ private VariableElement zField;
+
+ private VariableElement cField;
+
+ private VariableElement bField;
+
+ private VariableElement sField;
+
+ private VariableElement iField;
+
+ private VariableElement lField;
+
+ private VariableElement fField;
+
+ private VariableElement dField;
+
+ private VariableElement strField;
+
+ private VariableElement bdField;
+
+ private VariableElement biField;
+
+ private VariableElement dtField;
+
+ private VariableElement invalidField;
+
+
+ @Override
+ protected void addCompiledClasses(Set<Class<?>> classesToBeCompiled) {
+ classesToBeCompiled.add(SimpleTypeModel.class);
+ }
+
+ @Override
+ protected void beforeEach() {
+ builder = new SimpleTypeDefinitionBuilder();
+ TypeElement testType = getType(SimpleTypeModel.class);
+ vField = findField(testType, "v");
+ zField = findField(testType, "z");
+ cField = findField(testType, "c");
+ bField = findField(testType, "b");
+ sField = findField(testType, "s");
+ iField = findField(testType, "i");
+ lField = findField(testType, "l");
+ fField = findField(testType, "f");
+ dField = findField(testType, "d");
+ strField = findField(testType, "str");
+ bdField = findField(testType, "bd");
+ biField = findField(testType, "bi");
+ dtField = findField(testType, "dt");
+ invalidField = findField(testType, "invalid");
+
+ assertEquals("java.lang.Void", vField.asType().toString());
+ assertEquals("java.lang.Boolean", zField.asType().toString());
+ assertEquals("java.lang.Character", cField.asType().toString());
+ assertEquals("java.lang.Byte", bField.asType().toString());
+ assertEquals("java.lang.Short", sField.asType().toString());
+ assertEquals("java.lang.Integer", iField.asType().toString());
+ assertEquals("java.lang.Long", lField.asType().toString());
+ assertEquals("java.lang.Float", fField.asType().toString());
+ assertEquals("java.lang.Double", dField.asType().toString());
+ assertEquals("java.lang.String", strField.asType().toString());
+ assertEquals("java.math.BigDecimal", bdField.asType().toString());
+ assertEquals("java.math.BigInteger", biField.asType().toString());
+ assertEquals("java.util.Date", dtField.asType().toString());
+ assertEquals("int", invalidField.asType().toString());
+ }
+
+ @Test
+ public void testAccept() {
+ assertTrue(builder.accept(processingEnv, vField.asType()));
+ assertTrue(builder.accept(processingEnv, zField.asType()));
+ assertTrue(builder.accept(processingEnv, cField.asType()));
+ assertTrue(builder.accept(processingEnv, bField.asType()));
+ assertTrue(builder.accept(processingEnv, sField.asType()));
+ assertTrue(builder.accept(processingEnv, iField.asType()));
+ assertTrue(builder.accept(processingEnv, lField.asType()));
+ assertTrue(builder.accept(processingEnv, fField.asType()));
+ assertTrue(builder.accept(processingEnv, dField.asType()));
+ assertTrue(builder.accept(processingEnv, strField.asType()));
+ assertTrue(builder.accept(processingEnv, bdField.asType()));
+ assertTrue(builder.accept(processingEnv, biField.asType()));
+ assertTrue(builder.accept(processingEnv, dtField.asType()));
+ // false condition
+ assertFalse(builder.accept(processingEnv, invalidField.asType()));
+ }
+
+ @Test
+ public void testBuild() {
+ buildAndAssertTypeDefinition(processingEnv, vField, builder);
+ buildAndAssertTypeDefinition(processingEnv, zField, builder);
+ buildAndAssertTypeDefinition(processingEnv, cField, builder);
+ buildAndAssertTypeDefinition(processingEnv, sField, builder);
+ buildAndAssertTypeDefinition(processingEnv, iField, builder);
+ buildAndAssertTypeDefinition(processingEnv, lField, builder);
+ buildAndAssertTypeDefinition(processingEnv, fField, builder);
+ buildAndAssertTypeDefinition(processingEnv, dField, builder);
+ buildAndAssertTypeDefinition(processingEnv, strField, builder);
+ buildAndAssertTypeDefinition(processingEnv, bdField, builder);
+ buildAndAssertTypeDefinition(processingEnv, biField, builder);
+ buildAndAssertTypeDefinition(processingEnv, dtField, builder);
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/ArrayTypeModel.java
similarity index 60%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/ArrayTypeModel.java
index 57832cc..db6874a 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/ArrayTypeModel.java
@@ -14,24 +14,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.model;
/**
- * Object Utilities
+ * Array Type Model
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
+public class ArrayTypeModel {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
- }
+ 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
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/CollectionTypeModel.java
similarity index 53%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/CollectionTypeModel.java
index 57832cc..b2ce91d 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/CollectionTypeModel.java
@@ -14,24 +14,29 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.model;
+
+import java.util.Collection;
+import java.util.Deque;
+import java.util.List;
+import java.util.Queue;
+import java.util.Set;
/**
- * Object Utilities
+ * {@link Collection} Type Model
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
-
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
- }
+public class CollectionTypeModel {
+
+ private Collection<String> strings; // The composite element is simple type
+
+ private List<Color> colors; // The composite element is Enum type
+
+ private Queue<PrimitiveTypeModel> primitiveTypeModels; // The composite element is POJO type
+
+ private Deque<Model> models; // The composite element is hierarchical POJO type
+
+ private Set<Model[]> modelArrays; // The composite element is hierarchical POJO type
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/Color.java
similarity index 64%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/Color.java
index 57832cc..6c34404 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/Color.java
@@ -14,24 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.model;
/**
- * Object Utilities
+ * Color enumeration
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
+public enum Color {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
+ RED(1),
+ YELLOW(2),
+ BLUE(3);
+
+ private final int value;
+
+ Color(int value) {
+ this.value = value;
}
+ @Override
+ public String toString() {
+ return "Color{" +
+ "value=" + value +
+ "} " + super.toString();
+ }
+
+ public int getValue() {
+ return value;
+ }
}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/MapTypeModel.java
similarity index 51%
rename from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java
rename to dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/MapTypeModel.java
index 29cd637..f1613ae 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/MapTypeModel.java
@@ -14,24 +14,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.model;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.NavigableMap;
+import java.util.SortedMap;
+import java.util.TreeMap;
/**
- * {@link Class} Utilities
- * <p>
- * The source code is cloned from
- * https://github.com/alibaba/spring-context-support/blob/1.0.2/src/main/java/com/alibaba/spring/util/ClassUtils.java
+ * {@link Map} Type model
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ClassUtils {
+public class MapTypeModel {
- public static <T> Class<T> resolveGenericType(Class<?> declaredClass) {
- ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass();
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
- return (Class<T>) actualTypeArguments[0];
- }
+ private Map<String, String> strings; // The composite element is simple type
+
+ private SortedMap<String, Color> colors; // The composite element is Enum type
+
+ private NavigableMap<Color, PrimitiveTypeModel> primitiveTypeModels; // The composite element is POJO type
+
+ private HashMap<String, Model> models; // The composite element is hierarchical POJO type
+
+ private TreeMap<PrimitiveTypeModel, Model[]> modelArrays; // The composite element is hierarchical POJO type
}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/Model.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/Model.java
new file mode 100644
index 0000000..e3c72a5
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/Model.java
@@ -0,0 +1,89 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.model;
+
+import org.apache.dubbo.metadata.tools.Parent;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Model Object
+ */
+public class Model extends Parent {
+
+ private float f;
+
+ private double d;
+
+ private TimeUnit tu;
+
+ private String str;
+
+ private BigInteger bi;
+
+ private BigDecimal bd;
+
+ public float getF() {
+ return f;
+ }
+
+ public void setF(float f) {
+ this.f = f;
+ }
+
+ public double getD() {
+ return d;
+ }
+
+ public void setD(double d) {
+ this.d = d;
+ }
+
+ public TimeUnit getTu() {
+ return tu;
+ }
+
+ public void setTu(TimeUnit tu) {
+ this.tu = tu;
+ }
+
+ public String getStr() {
+ return str;
+ }
+
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ public BigInteger getBi() {
+ return bi;
+ }
+
+ public void setBi(BigInteger bi) {
+ this.bi = bi;
+ }
+
+ public BigDecimal getBd() {
+ return bd;
+ }
+
+ public void setBd(BigDecimal bd) {
+ this.bd = bd;
+ }
+}
diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/PrimitiveTypeModel.java
similarity index 53%
copy from dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
copy to dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/PrimitiveTypeModel.java
index 57832cc..7adc685 100644
--- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/PrimitiveTypeModel.java
@@ -14,24 +14,60 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.config.spring.util;
+package org.apache.dubbo.metadata.annotation.processing.model;
/**
- * Object Utilities
+ * Primitive Type model
*
- * @since 2.6.6
+ * @since 2.7.5
*/
-public abstract class ObjectUtils {
+public class PrimitiveTypeModel {
- /**
- * Convert from variable arguments to array
- *
- * @param values variable arguments
- * @param <T> The class
- * @return array
- */
- public static <T> T[] of(T... values) {
- return values;
+ private boolean z;
+
+ private byte b;
+
+ private char c;
+
+ private short s;
+
+ private int i;
+
+ private long l;
+
+ private float f;
+
+ private double d;
+
+ public boolean isZ() {
+ return z;
}
+ public byte getB() {
+ return b;
+ }
+
+ public char getC() {
+ return c;
+ }
+
+ public short getS() {
+ return s;
+ }
+
+ public int getI() {
+ return i;
+ }
+
+ public long getL() {
+ return l;
+ }
+
+ public float getF() {
+ return f;
+ }
+
+ public double getD() {
+ return d;
+ }
}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/SimpleTypeModel.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/SimpleTypeModel.java
new file mode 100644
index 0000000..b6f40ec
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/model/SimpleTypeModel.java
@@ -0,0 +1,161 @@
+/*
+ * 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 org.apache.dubbo.metadata.annotation.processing.model;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+/**
+ * Simple Type model
+ *
+ * @since 2.7.5
+ */
+public class SimpleTypeModel {
+
+ private Void v;
+
+ private Boolean z;
+
+ private Character c;
+
+ private Byte b;
+
+ private Short s;
+
+ private Integer i;
+
+ private Long l;
+
+ private Float f;
+
+ private Double d;
+
+ private String str;
+
+ private BigDecimal bd;
+
+ private BigInteger bi;
+
+ private Date dt;
+
+ private int invalid;
+
+ public Void getV() {
+ return v;
+ }
+
+ public void setV(Void v) {
+ this.v = v;
+ }
+
+ public Boolean getZ() {
+ return z;
+ }
+
+ public void setZ(Boolean z) {
+ this.z = z;
+ }
+
+ public Character getC() {
+ return c;
+ }
+
+ public void setC(Character c) {
+ this.c = c;
+ }
+
+ public Byte getB() {
+ return b;
+ }
+
+ public void setB(Byte b) {
+ this.b = b;
+ }
+
+ public Short getS() {
+ return s;
+ }
+
+ public void setS(Short s) {
+ this.s = s;
+ }
+
+ public Integer getI() {
+ return i;
+ }
+
+ public void setI(Integer i) {
+ this.i = i;
+ }
+
+ public Long getL() {
+ return l;
+ }
+
+ public void setL(Long l) {
+ this.l = l;
+ }
+
+ public Float getF() {
+ return f;
+ }
+
+ public void setF(Float f) {
+ this.f = f;
+ }
+
+ public Double getD() {
+ return d;
+ }
+
+ public void setD(Double d) {
+ this.d = d;
+ }
+
+ public String getStr() {
+ return str;
+ }
+
+ public void setStr(String str) {
+ this.str = str;
+ }
+
+ public BigDecimal getBd() {
+ return bd;
+ }
+
+ public void setBd(BigDecimal bd) {
+ this.bd = bd;
+ }
+
+ public BigInteger getBi() {
+ return bi;
+ }
+
+ public void setBi(BigInteger bi) {
+ this.bi = bi;
+ }
+
+ public Date getDt() {
+ return dt;
+ }
+
+ public void setDt(Date dt) {
+ this.dt = dt;
+ }
+}
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/rest/AnnotatedMethodParameterProcessorTest.java b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/rest/AnnotatedMethodParameterProcessorTest.java
new file mode 100644
index 0000000..5b6a4d6
--- /dev/null
+++ b/dubbo-metadata/dubbo-metadata-processor/src/test/java/org/apache/dubbo/metadata/annotation/processing/rest/AnnotatedMethodParameterProcessorTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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
... 2660 lines suppressed ...