Revert "revert metadata related changes"
This reverts commit 50315fe3d1.
This commit is contained in:
parent
8d7e483bbd
commit
a7a26d8977
|
|
@ -25,7 +25,7 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad
|
|||
/**
|
||||
* The factory interface to create the instance of {@link DynamicConfiguration}
|
||||
*/
|
||||
@SPI("file") // 2.7.5 change the default SPI implementation
|
||||
@SPI("nop")
|
||||
public interface DynamicConfigurationFactory {
|
||||
|
||||
DynamicConfiguration getDynamicConfiguration(URL url);
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ 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;
|
||||
|
|
@ -41,8 +40,7 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
|
@ -51,17 +49,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>
|
||||
|
|
@ -406,7 +404,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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -434,16 +432,14 @@ public class ExtensionLoader<T> {
|
|||
}
|
||||
|
||||
public Set<T> getSupportedExtensionInstances() {
|
||||
List<T> instances = new LinkedList<>();
|
||||
Set<T> instances = new HashSet<>();
|
||||
Set<String> supportedExtensions = getSupportedExtensions();
|
||||
if (CollectionUtils.isNotEmpty(supportedExtensions)) {
|
||||
for (String name : supportedExtensions) {
|
||||
instances.add(getExtension(name));
|
||||
}
|
||||
}
|
||||
// sort the Prioritized instances
|
||||
sort(instances, Prioritized.COMPARATOR);
|
||||
return new LinkedHashSet<>(instances);
|
||||
return instances;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -716,7 +712,7 @@ public class ExtensionLoader<T> {
|
|||
|
||||
/**
|
||||
* synchronized in getExtensionClasses
|
||||
*/
|
||||
* */
|
||||
private Map<String, Class<?>> loadExtensionClasses() {
|
||||
cacheDefaultExtensionName();
|
||||
|
||||
|
|
@ -763,7 +759,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();
|
||||
|
|
@ -771,8 +767,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 {
|
||||
|
|
|
|||
|
|
@ -1,74 +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.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,71 +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.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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -21,14 +21,8 @@ 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 {
|
||||
|
||||
|
|
@ -179,7 +173,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;
|
||||
}
|
||||
|
||||
|
|
@ -227,17 +221,4 @@ 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)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ 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;
|
||||
|
|
@ -59,34 +58,6 @@ 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() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,10 +62,8 @@ 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 {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
|
||||
|
||||
public static final String NAME = "config";
|
||||
private static final Logger logger = LoggerFactory.getLogger(ConfigManager.class);
|
||||
|
||||
private final Map<String, Map<String, AbstractConfig>> configsCache = newMap();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,60 +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.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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -24,25 +24,21 @@ 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 org.hamcrest.MatcherAssert.assertThat;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singleton;
|
||||
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 {
|
||||
|
|
@ -199,20 +195,4 @@ 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,223 +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.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();
|
||||
}
|
||||
}
|
||||
|
|
@ -67,124 +67,29 @@
|
|||
</dependency>
|
||||
|
||||
<!-- 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>
|
||||
|
|
|
|||
|
|
@ -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=dubbo-nacos-provider-demo"))
|
||||
.registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=service-provider"))
|
||||
.metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
|
||||
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
|
||||
.start();
|
||||
|
|
|
|||
|
|
@ -32,17 +32,18 @@ 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();
|
||||
.start()
|
||||
.await();
|
||||
|
||||
EchoService echoService = bootstrap.getCache().get(EchoService.class);
|
||||
UserService userService = bootstrap.getCache().get(UserService.class);
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int i = 0; i < 500; i++) {
|
||||
Thread.sleep(2000L);
|
||||
System.out.println(echoService.echo("Hello,World"));
|
||||
System.out.println(userService.getUser(i * 1L));
|
||||
}
|
||||
|
||||
bootstrap.stop();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,12 +56,6 @@
|
|||
<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>
|
||||
|
|
|
|||
|
|
@ -30,8 +30,8 @@ import org.springframework.util.Assert;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.spring.util.BeanFactoryUtils.getBeans;
|
||||
import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
|
||||
import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getBeans;
|
||||
import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getNullableBean;
|
||||
|
||||
/**
|
||||
* Abstract Configurable {@link Annotation} Bean Builder
|
||||
|
|
@ -132,7 +132,7 @@ abstract class AbstractAnnotationConfigBeanBuilder<A extends Annotation, B exten
|
|||
|
||||
String monitorBeanName = resolveMonitorConfigBeanName(annotation);
|
||||
|
||||
MonitorConfig monitorConfig = getOptionalBean(applicationContext, monitorBeanName, MonitorConfig.class);
|
||||
MonitorConfig monitorConfig = getNullableBean(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 =
|
||||
getOptionalBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
|
||||
getNullableBean(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 =
|
||||
getOptionalBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
|
||||
getNullableBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
|
||||
|
||||
bean.setModule(moduleConfig);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@ import org.springframework.util.Assert;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.util.List;
|
||||
|
||||
import static com.alibaba.spring.util.BeanFactoryUtils.getBeans;
|
||||
import static com.alibaba.spring.util.BeanFactoryUtils.getOptionalBean;
|
||||
import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getBeans;
|
||||
import static org.apache.dubbo.config.spring.util.BeanFactoryUtils.getNullableBean;
|
||||
|
||||
/**
|
||||
* 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 = getOptionalBean(applicationContext, monitorBeanName, MonitorConfig.class);
|
||||
MonitorConfig monitorConfig = getNullableBean(applicationContext, monitorBeanName, MonitorConfig.class);
|
||||
|
||||
configBean.setMonitor(monitorConfig);
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInte
|
|||
String applicationConfigBeanName = resolveApplicationConfigBeanName(attributes);
|
||||
|
||||
ApplicationConfig applicationConfig =
|
||||
getOptionalBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
|
||||
getNullableBean(applicationContext, applicationConfigBeanName, ApplicationConfig.class);
|
||||
|
||||
configBean.setApplication(applicationConfig);
|
||||
|
||||
|
|
@ -155,7 +155,7 @@ public abstract class AnnotatedInterfaceConfigBeanBuilder<C extends AbstractInte
|
|||
String moduleConfigBeanName = resolveModuleConfigBeanName(attributes);
|
||||
|
||||
ModuleConfig moduleConfig =
|
||||
getOptionalBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
|
||||
getNullableBean(applicationContext, moduleConfigBeanName, ModuleConfig.class);
|
||||
|
||||
configBean.setModule(moduleConfig);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,548 @@
|
|||
/*
|
||||
* 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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,8 @@ import org.springframework.core.env.PropertyResolver;
|
|||
import java.lang.annotation.Annotation;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttributes;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttributes;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolvePlaceholders;
|
||||
|
||||
/**
|
||||
* {@link Annotation} {@link PropertyValues} Adapter
|
||||
|
|
@ -45,7 +46,7 @@ class AnnotationPropertyValuesAdapter implements PropertyValues {
|
|||
*/
|
||||
public AnnotationPropertyValuesAdapter(Map<String, Object> attributes, PropertyResolver propertyResolver,
|
||||
String... ignoreAttributeNames) {
|
||||
this.delegate = new MutablePropertyValues(getAttributes(attributes, propertyResolver, ignoreAttributeNames));
|
||||
this.delegate = new MutablePropertyValues(resolvePlaceholders(attributes, propertyResolver, ignoreAttributeNames));
|
||||
}
|
||||
|
||||
public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver,
|
||||
|
|
|
|||
|
|
@ -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 com.alibaba.spring.util.BeanRegistrar.hasAlias;
|
||||
import static org.apache.dubbo.config.spring.util.BeanRegistrar.hasAlias;
|
||||
import static org.springframework.util.ObjectUtils.nullSafeEquals;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
|
||||
|
|
|
|||
|
|
@ -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,10 +44,9 @@ 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;
|
||||
|
||||
/**
|
||||
|
|
@ -56,7 +55,7 @@ import static org.springframework.util.StringUtils.hasText;
|
|||
*
|
||||
* @since 2.5.7
|
||||
*/
|
||||
public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBeanPostProcessor implements
|
||||
public class ReferenceAnnotationBeanPostProcessor extends AnnotationInjectedBeanPostProcessor implements
|
||||
ApplicationContextAware, ApplicationListener {
|
||||
|
||||
/**
|
||||
|
|
@ -300,7 +299,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean
|
|||
Class<?> injectedType, InjectionMetadata.InjectedElement injectedElement) {
|
||||
return buildReferencedBeanName(attributes, injectedType) +
|
||||
"#source=" + (injectedElement.getMember()) +
|
||||
"#attributes=" + getAttributes(attributes, getEnvironment());
|
||||
"#attributes=" + AnnotationUtils.resolvePlaceholders(attributes, getEnvironment());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -34,11 +34,11 @@ import java.beans.PropertyEditorSupport;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
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.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 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 = getOptionalBean(applicationContext, consumerBeanName, ConsumerConfig.class);
|
||||
ConsumerConfig consumerConfig = getNullableBean(applicationContext, consumerBeanName, ConsumerConfig.class);
|
||||
|
||||
referenceBean.setConsumer(consumerConfig);
|
||||
|
||||
|
|
|
|||
|
|
@ -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.DubboAnnotationUtils.resolveServiceInterfaceClass;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveServiceInterfaceClass;
|
||||
import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import org.springframework.core.annotation.AnnotationAttributes;
|
|||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotationUtils.getAttribute;
|
||||
import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveInterfaceName;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotationUtils.getAttribute;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotationUtils.resolveInterfaceName;
|
||||
import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ 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;
|
||||
|
|
@ -36,7 +37,6 @@ 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
|
||||
registerInfrastructureBean(registry,
|
||||
BeanRegistrar.registerInfrastructureBean(registry,
|
||||
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ 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;
|
||||
|
|
@ -44,13 +43,12 @@ 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
|
||||
|
|
@ -58,9 +56,7 @@ import static org.springframework.core.annotation.AnnotationAttributes.fromMap;
|
|||
* @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 {
|
||||
|
||||
|
|
@ -71,7 +67,8 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
|
|||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
|
||||
|
||||
AnnotationAttributes attributes = fromMap(importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBinding.class.getName()));
|
||||
AnnotationAttributes attributes = AnnotationAttributes.fromMap(
|
||||
importingClassMetadata.getAnnotationAttributes(EnableDubboConfigBinding.class.getName()));
|
||||
|
||||
registerBeanDefinitions(attributes, registry);
|
||||
|
||||
|
|
@ -94,7 +91,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
|
|||
boolean multiple,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Map<String, Object> properties = getSubProperties(environment.getPropertySources(), prefix);
|
||||
Map<String, Object> properties = getPrefixedProperties(environment.getPropertySources(), prefix);
|
||||
|
||||
if (CollectionUtils.isEmpty(properties)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
|
|
@ -147,7 +144,7 @@ public class DubboConfigBindingRegistrar implements ImportBeanDefinitionRegistra
|
|||
|
||||
BeanDefinitionBuilder builder = rootBeanDefinition(processorClass);
|
||||
|
||||
String actualPrefix = multiple ? normalizePrefix(prefix) + beanName : prefix;
|
||||
String actualPrefix = multiple ? buildPrefix(prefix) + beanName : prefix;
|
||||
|
||||
builder.addConstructorArgValue(actualPrefix).addConstructorArgValue(beanName);
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ 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;
|
||||
|
|
@ -34,9 +33,7 @@ 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;
|
||||
|
|
|
|||
|
|
@ -28,17 +28,14 @@ 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 EnableConfigurationBeanBindings
|
||||
* @see EnableConfigurationBeanBinding
|
||||
* @see EnableDubboConfigBindings
|
||||
* @see EnableDubboConfigBinding
|
||||
* @see ApplicationConfig
|
||||
* @see ModuleConfig
|
||||
* @see RegistryConfig
|
||||
|
|
@ -54,17 +51,17 @@ public class DubboConfigConfiguration {
|
|||
/**
|
||||
* Single Dubbo {@link AbstractConfig Config} Bean Binding
|
||||
*/
|
||||
@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)
|
||||
@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)
|
||||
})
|
||||
public static class Single {
|
||||
|
||||
|
|
@ -73,17 +70,17 @@ public class DubboConfigConfiguration {
|
|||
/**
|
||||
* Multiple Dubbo {@link AbstractConfig Config} Bean Binding
|
||||
*/
|
||||
@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)
|
||||
@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)
|
||||
})
|
||||
public static class Multiple {
|
||||
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ import org.springframework.core.Ordered;
|
|||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
|
||||
import static com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
|
||||
import static com.alibaba.spring.util.BeanRegistrar.registerInfrastructureBean;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
|
||||
import static org.apache.dubbo.config.spring.util.BeanRegistrar.registerInfrastructureBean;
|
||||
|
||||
/**
|
||||
* Dubbo {@link AbstractConfig Config} {@link ImportBeanDefinitionRegistrar register}, which order can be configured
|
||||
|
|
|
|||
|
|
@ -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 com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
|
||||
|
||||
/**
|
||||
* A {@link ImportBeanDefinitionRegistrar register} for the {@link Lifecycle Dubbo Lifecycle} components
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ 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;
|
||||
|
||||
|
|
@ -45,16 +44,13 @@ 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 {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
*/
|
||||
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;
|
||||
|
|
@ -29,15 +28,13 @@ import java.lang.annotation.Target;
|
|||
/**
|
||||
* Multiple {@link EnableDubboConfigBinding} {@link Annotation}
|
||||
*
|
||||
* @see EnableDubboConfigBinding
|
||||
* @since 2.5.8
|
||||
* @deprecated it will be removed in future, please use {@link EnableConfigurationBeanBindings} for replacement
|
||||
* @see EnableDubboConfigBinding
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import(DubboConfigBindingsRegistrar.class)
|
||||
@Deprecated
|
||||
public @interface EnableDubboConfigBindings {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ import java.beans.PropertyDescriptor;
|
|||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.alibaba.spring.util.ObjectUtils.of;
|
||||
import static org.apache.dubbo.config.spring.util.ObjectUtils.of;
|
||||
import static org.springframework.beans.BeanUtils.getPropertyDescriptor;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import org.springframework.validation.DataBinder;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties;
|
||||
import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getPrefixedProperties;
|
||||
|
||||
/**
|
||||
* 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 = getSubProperties(getPropertySources(), prefix);
|
||||
Map<String, Object> properties = getPrefixedProperties(getPropertySources(), prefix);
|
||||
// Convert Map to MutablePropertyValues
|
||||
MutablePropertyValues propertyValues = new MutablePropertyValues(properties);
|
||||
// Bind
|
||||
|
|
|
|||
|
|
@ -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.ApplicationContextUtils;
|
||||
import org.apache.dubbo.config.spring.util.BeanFactoryUtils;
|
||||
|
||||
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();
|
||||
}
|
||||
ApplicationContextUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);
|
||||
BeanFactoryUtils.addApplicationListener(context, SHUTDOWN_HOOK_LISTENER);
|
||||
}
|
||||
|
||||
public static void removeApplicationContext(ApplicationContext context) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ 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;
|
||||
|
|
@ -27,12 +28,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
|
||||
|
|
@ -78,7 +79,7 @@ public class AnnotationBeanDefinitionParser extends AbstractSingleBeanDefinition
|
|||
private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
|
||||
|
||||
// Register @Reference Annotation Bean Processor
|
||||
registerInfrastructureBean(registry,
|
||||
BeanRegistrar.registerInfrastructureBean(registry,
|
||||
ReferenceAnnotationBeanPostProcessor.BEAN_NAME, ReferenceAnnotationBeanPostProcessor.class);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 com.alibaba.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
|
||||
import static org.apache.dubbo.config.spring.util.AnnotatedBeanDefinitionRegistryUtils.registerBeans;
|
||||
|
||||
/**
|
||||
* DubboNamespaceHandler
|
||||
|
|
|
|||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,12 +17,19 @@
|
|||
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
|
||||
|
|
@ -32,7 +39,7 @@ import java.lang.reflect.Method;
|
|||
* @see org.springframework.beans.factory.BeanFactoryUtils
|
||||
* @since 2.5.7
|
||||
*/
|
||||
public class ApplicationContextUtils {
|
||||
public class BeanFactoryUtils {
|
||||
|
||||
public static boolean addApplicationListener(ApplicationContext applicationContext, ApplicationListener listener) {
|
||||
try {
|
||||
|
|
@ -57,4 +64,51 @@ public class ApplicationContextUtils {
|
|||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -14,19 +14,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.metadata.annotation.processing.rest.jaxrs;
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @FormParam
|
||||
* {@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
|
||||
*
|
||||
* @since 2.7.5
|
||||
* @since 2.6.6
|
||||
*/
|
||||
public class FormParamParameterProcessor extends ParamAnnotationParameterProcessor {
|
||||
public abstract class ClassUtils {
|
||||
|
||||
@Override
|
||||
public String getAnnotationType() {
|
||||
return "javax.ws.rs.FormParam";
|
||||
public static <T> Class<T> resolveGenericType(Class<?> declaredClass) {
|
||||
ParameterizedType parameterizedType = (ParameterizedType) declaredClass.getGenericSuperclass();
|
||||
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
|
||||
return (Class<T>) actualTypeArguments[0];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,150 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -14,22 +14,24 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.dubbo.metadata.tools;
|
||||
|
||||
import java.io.Serializable;
|
||||
package org.apache.dubbo.config.spring.util;
|
||||
|
||||
/**
|
||||
* Ancestor
|
||||
* Object Utilities
|
||||
*
|
||||
* @since 2.6.6
|
||||
*/
|
||||
public class Ancestor implements Serializable {
|
||||
public abstract class ObjectUtils {
|
||||
|
||||
private boolean z;
|
||||
|
||||
public boolean isZ() {
|
||||
return z;
|
||||
/**
|
||||
* 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 void setZ(boolean z) {
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* 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 + ".";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -97,19 +97,17 @@ public class ReferenceAnnotationBeanPostProcessorTest {
|
|||
TestBean testBean = context.getBean(TestBean.class);
|
||||
|
||||
DemoService demoService = testBean.getDemoService();
|
||||
Map<String, DemoService> demoServicesMap = context.getBeansOfType(DemoService.class);
|
||||
|
||||
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(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.assertEquals("Hello,Mercy", testBean.getDemoServiceFromAncestor().sayName("Mercy"));
|
||||
Assert.assertEquals("Hello,Mercy", testBean.getDemoServiceFromParent().sayName("Mercy"));
|
||||
|
|
@ -120,6 +118,9 @@ 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()) {
|
||||
|
||||
|
|
@ -164,7 +165,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
|
|||
|
||||
InjectionMetadata.InjectedElement injectedElement = entry.getKey();
|
||||
|
||||
Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor$AnnotatedFieldElement",
|
||||
Assert.assertEquals("org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedFieldElement",
|
||||
injectedElement.getClass().getName());
|
||||
|
||||
}
|
||||
|
|
@ -186,7 +187,7 @@ public class ReferenceAnnotationBeanPostProcessorTest {
|
|||
|
||||
InjectionMetadata.InjectedElement injectedElement = entry.getKey();
|
||||
|
||||
Assert.assertEquals("com.alibaba.spring.beans.factory.annotation.AbstractAnnotationBeanPostProcessor$AnnotatedMethodElement",
|
||||
Assert.assertEquals("org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationInjectedBeanPostProcessor$AnnotatedMethodElement",
|
||||
injectedElement.getClass().getName());
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,11 +32,10 @@ import org.springframework.context.annotation.PropertySource;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.alibaba.spring.util.BeanRegistrar.hasAlias;
|
||||
import static org.apache.dubbo.config.spring.util.BeanRegistrar.hasAlias;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
|
||||
/**
|
||||
* {@link EnableDubboConfig} Test
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,46 +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.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;
|
||||
|
||||
/**
|
||||
* {@link ApplicationContextUtils} Test
|
||||
*
|
||||
* @since 2.5.7
|
||||
*/
|
||||
public class ApplicationContextUtilsTest {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
applicationContext = new GenericApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddApplicationListener() {
|
||||
assertTrue(addApplicationListener(applicationContext, event -> {
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.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);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -144,9 +144,6 @@
|
|||
<!-- 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>
|
||||
|
|
@ -280,14 +277,6 @@
|
|||
<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>
|
||||
|
|
|
|||
|
|
@ -27,12 +27,11 @@ 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 {
|
||||
|
||||
|
|
@ -55,14 +54,13 @@ public class DynamicConfigurationServiceNameMapping implements ServiceNameMappin
|
|||
|
||||
// the Dubbo Service Key as group
|
||||
// the service(application) name as key
|
||||
// It does not matter whatever the content is, we just need a record
|
||||
String key = ApplicationModel.getApplication();
|
||||
String content = String.valueOf(System.currentTimeMillis());
|
||||
// It does matter whatever the content is, we just need a record
|
||||
String app = ApplicationModel.getApplication();
|
||||
execute(() -> {
|
||||
dynamicConfiguration.publishConfig(key, buildGroup(serviceInterface, group, version, protocol), content);
|
||||
dynamicConfiguration.publishConfig(buildKey(serviceInterface, group, version, protocol), app);
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info(String.format("The Dubbo service key[%s] mapped to service name[%s] with content : %s",
|
||||
key, group, content));
|
||||
logger.info(String.format("Dubbo service[%s] mapped to interface name[%s].",
|
||||
app, serviceInterface, app));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -72,17 +70,15 @@ public class DynamicConfigurationServiceNameMapping implements ServiceNameMappin
|
|||
|
||||
DynamicConfiguration dynamicConfiguration = DynamicConfiguration.getDynamicConfiguration();
|
||||
|
||||
String key = ApplicationModel.getApplication();
|
||||
|
||||
Set<String> serviceNames = new LinkedHashSet<>();
|
||||
execute(() -> {
|
||||
Set<String> keys = dynamicConfiguration.getConfigKeys(buildGroup(serviceInterface, group, version, protocol), key);
|
||||
Set<String> keys = dynamicConfiguration.getConfigKeys(DEFAULT_MAPPING_GROUP, buildKey(serviceInterface, group, version, protocol));
|
||||
serviceNames.addAll(keys);
|
||||
});
|
||||
return Collections.unmodifiableSet(serviceNames);
|
||||
}
|
||||
|
||||
protected static String buildGroup(String serviceInterface, String group, String version, String protocol) {
|
||||
protected static String buildKey(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))
|
||||
|
|
|
|||
|
|
@ -1,225 +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.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 + '}';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,187 +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.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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,103 +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.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();
|
||||
}
|
||||
}
|
||||
|
|
@ -4,17 +4,20 @@ 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());
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -1,266 +0,0 @@
|
|||
/*
|
||||
* 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);
|
||||
// }
|
||||
}
|
||||
|
|
@ -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.buildGroup;
|
||||
import static org.apache.dubbo.metadata.DynamicConfigurationServiceNameMapping.buildKey;
|
||||
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", 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"));
|
||||
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"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ 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;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ 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;
|
||||
|
|
@ -33,6 +34,8 @@ 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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,161 +0,0 @@
|
|||
<?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>
|
||||
|
|
@ -1,108 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,105 +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.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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,60 +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.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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +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.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);
|
||||
}
|
||||
|
|
@ -1,55 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,65 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,53 +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.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());
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,95 +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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,52 +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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,234 +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.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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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.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 + "}";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,59 +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.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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,55 +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.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);
|
||||
}
|
||||
|
|
@ -1,66 +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.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,50 +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.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));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,113 +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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +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.metadata.annotation.processing.rest.jaxrs;
|
||||
|
||||
import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
|
||||
|
||||
/**
|
||||
* The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @MatrixParam
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class MatrixParamParameterProcessor extends ParamAnnotationParameterProcessor {
|
||||
|
||||
@Override
|
||||
public String getAnnotationType() {
|
||||
return "javax.ws.rs.MatrixParam";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,38 +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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +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.metadata.annotation.processing.rest.jaxrs;
|
||||
|
||||
import org.apache.dubbo.metadata.annotation.processing.rest.AnnotatedMethodParameterProcessor;
|
||||
|
||||
/**
|
||||
* The {@link AnnotatedMethodParameterProcessor} implementation for JAX-RS's @QueryParam
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class QueryParamParameterProcessor extends ParamAnnotationParameterProcessor {
|
||||
|
||||
@Override
|
||||
public String getAnnotationType() {
|
||||
return "javax.ws.rs.QueryParam";
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +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.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();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,41 +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.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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,44 +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.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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,157 +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.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];
|
||||
}
|
||||
}
|
||||
|
|
@ -1,233 +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.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");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,146 +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.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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,45 +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.metadata.annotation.processing.util;
|
||||
|
||||
|
||||
import org.apache.dubbo.common.logger.Logger;
|
||||
import org.apache.dubbo.common.logger.LoggerFactory;
|
||||
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Logger Utils
|
||||
*
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public interface LoggerUtils {
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,94 +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.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;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue