This is an automated email from the ASF dual-hosted git repository. zhangliang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push: new 100b61e1739 Add YamlRuleConfigurationReflectionEngine (#34874) 100b61e1739 is described below commit 100b61e173934e7af52d3750c93de1c69958ae76 Author: Liang Zhang <zhangli...@apache.org> AuthorDate: Wed Mar 5 00:18:55 2025 +0800 Add YamlRuleConfigurationReflectionEngine (#34874) * Add YamlRuleConfigurationReflectionEngine * Add YamlRuleConfigurationReflectionEngine --- .../shortcut/YamlRuleConfigurationShortcuts.java | 4 +- .../node/rule/node/DatabaseRuleNodeGenerator.java | 22 +++--- .../rule/tuple/YamlRuleConfigurationFieldUtil.java | 59 --------------- .../YamlRuleConfigurationReflectionEngine.java | 87 ++++++++++++++++++++++ .../rule/tuple/YamlRuleNodeTupleSwapperEngine.java | 58 ++++----------- 5 files changed, 113 insertions(+), 117 deletions(-) diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/yaml/config/shortcut/YamlRuleConfigurationShortcuts.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/yaml/config/shortcut/YamlRuleConfigurationShortcuts.java index a1daf8572d6..745ddc63514 100644 --- a/infra/common/src/main/java/org/apache/shardingsphere/infra/yaml/config/shortcut/YamlRuleConfigurationShortcuts.java +++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/yaml/config/shortcut/YamlRuleConfigurationShortcuts.java @@ -39,8 +39,8 @@ public final class YamlRuleConfigurationShortcuts implements ShardingSphereYamlS Collection<YamlRuleConfigurationSwapper> swappers = ShardingSphereServiceLoader.getServiceInstances(YamlRuleConfigurationSwapper.class); Map<String, Class<?>> result = new HashMap<>(swappers.size(), 1F); for (YamlRuleConfigurationSwapper each : swappers) { - Class<?> yamlRuleConfigurationClass = Class.forName(((ParameterizedType) each.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0].getTypeName()); - result.put(String.format("!%s", each.getRuleTagName()), yamlRuleConfigurationClass); + Class<?> yamlRuleConfigClass = Class.forName(((ParameterizedType) each.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0].getTypeName()); + result.put(String.format("!%s", each.getRuleTagName()), yamlRuleConfigClass); } return result; } diff --git a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/node/DatabaseRuleNodeGenerator.java b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/node/DatabaseRuleNodeGenerator.java index 1067d865153..8c9b78d8ed2 100644 --- a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/node/DatabaseRuleNodeGenerator.java +++ b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/node/DatabaseRuleNodeGenerator.java @@ -23,7 +23,7 @@ import lombok.NoArgsConstructor; import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader; import org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration; import org.apache.shardingsphere.infra.yaml.config.swapper.rule.YamlRuleConfigurationSwapper; -import org.apache.shardingsphere.mode.node.rule.tuple.YamlRuleConfigurationFieldUtil; +import org.apache.shardingsphere.mode.node.rule.tuple.YamlRuleConfigurationReflectionEngine; import org.apache.shardingsphere.mode.node.rule.tuple.annotation.RuleNodeTupleEntity; import org.apache.shardingsphere.mode.node.rule.tuple.annotation.RuleNodeTupleField; import org.apache.shardingsphere.mode.node.rule.tuple.annotation.RuleNodeTupleKeyListNameGenerator; @@ -45,19 +45,19 @@ public final class DatabaseRuleNodeGenerator { /** * Generate database rule node. * - * @param yamlRuleConfigurationClass YAML rule configuration class + * @param yamlRuleConfigClass YAML rule configuration class * @return generated database rule node */ - public static DatabaseRuleNode generate(final Class<? extends YamlRuleConfiguration> yamlRuleConfigurationClass) { - RuleNodeTupleEntity tupleEntity = yamlRuleConfigurationClass.getAnnotation(RuleNodeTupleEntity.class); - Preconditions.checkNotNull(tupleEntity, "Can not find @RuleNodeTupleEntity on class: ", yamlRuleConfigurationClass.getName()); + public static DatabaseRuleNode generate(final Class<? extends YamlRuleConfiguration> yamlRuleConfigClass) { + RuleNodeTupleEntity tupleEntity = yamlRuleConfigClass.getAnnotation(RuleNodeTupleEntity.class); + Preconditions.checkNotNull(tupleEntity, "Can not find @RuleNodeTupleEntity on class: ", yamlRuleConfigClass.getName()); Collection<String> namedItems = new LinkedList<>(); Collection<String> uniqueItems = new LinkedList<>(); - for (Field each : YamlRuleConfigurationFieldUtil.getFields(yamlRuleConfigurationClass)) { + for (Field each : YamlRuleConfigurationReflectionEngine.getFields(yamlRuleConfigClass)) { if (null == each.getAnnotation(RuleNodeTupleField.class)) { continue; } - String tupleName = YamlRuleConfigurationFieldUtil.getTupleItemName(each); + String tupleName = YamlRuleConfigurationReflectionEngine.getRuleNodeItemName(each); if (each.getType().equals(Map.class) || each.getType().equals(Collection.class) && null != each.getAnnotation(RuleNodeTupleKeyListNameGenerator.class)) { namedItems.add(tupleName); } else { @@ -79,13 +79,13 @@ public final class DatabaseRuleNodeGenerator { private static Optional<Class<? extends YamlRuleConfiguration>> findYamlRuleConfigurationClass(final String ruleType) { for (YamlRuleConfigurationSwapper<?, ?> each : ShardingSphereServiceLoader.getServiceInstances(YamlRuleConfigurationSwapper.class)) { - Optional<Class<? extends YamlRuleConfiguration>> yamlRuleConfigurationClass = findYamlRuleConfigurationClass(each.getClass()); - if (!yamlRuleConfigurationClass.isPresent()) { + Optional<Class<? extends YamlRuleConfiguration>> yamlRuleConfigClass = findYamlRuleConfigurationClass(each.getClass()); + if (!yamlRuleConfigClass.isPresent()) { continue; } - RuleNodeTupleEntity entity = yamlRuleConfigurationClass.get().getAnnotation(RuleNodeTupleEntity.class); + RuleNodeTupleEntity entity = yamlRuleConfigClass.get().getAnnotation(RuleNodeTupleEntity.class); if (null != entity && entity.value().equals(ruleType)) { - return yamlRuleConfigurationClass; + return yamlRuleConfigClass; } } return Optional.empty(); diff --git a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleConfigurationFieldUtil.java b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleConfigurationFieldUtil.java deleted file mode 100644 index 3d06b95bb15..00000000000 --- a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleConfigurationFieldUtil.java +++ /dev/null @@ -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.shardingsphere.mode.node.rule.tuple; - -import com.google.common.base.CaseFormat; -import lombok.AccessLevel; -import lombok.NoArgsConstructor; -import org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration; -import org.apache.shardingsphere.mode.node.rule.tuple.annotation.RuleNodeTupleField; - -import java.lang.reflect.Field; -import java.util.Arrays; -import java.util.Collection; -import java.util.Comparator; -import java.util.stream.Collectors; - -/** - * YAML rule configuration field utility class. - */ -@NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class YamlRuleConfigurationFieldUtil { - - /** - * Get fields from YAML rule configuration. - * - * @param yamlRuleConfigurationClass YAML rule configuration class - * @return got fields - */ - public static Collection<Field> getFields(final Class<? extends YamlRuleConfiguration> yamlRuleConfigurationClass) { - return Arrays.stream(yamlRuleConfigurationClass.getDeclaredFields()) - .filter(each -> null != each.getAnnotation(RuleNodeTupleField.class)) - .sorted(Comparator.comparingInt(o -> o.getAnnotation(RuleNodeTupleField.class).type().ordinal())).collect(Collectors.toList()); - } - - /** - * Get tuple item name. - * - * @param field field from YAML rule configuration - * @return tuple item name - */ - public static String getTupleItemName(final Field field) { - return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()); - } -} diff --git a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleConfigurationReflectionEngine.java b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleConfigurationReflectionEngine.java new file mode 100644 index 00000000000..57b9976a3ac --- /dev/null +++ b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleConfigurationReflectionEngine.java @@ -0,0 +1,87 @@ +/* + * 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.shardingsphere.mode.node.rule.tuple; + +import com.google.common.base.CaseFormat; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader; +import org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration; +import org.apache.shardingsphere.infra.yaml.config.swapper.rule.YamlRuleConfigurationSwapper; +import org.apache.shardingsphere.mode.node.rule.tuple.annotation.RuleNodeTupleEntity; +import org.apache.shardingsphere.mode.node.rule.tuple.annotation.RuleNodeTupleField; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.util.Arrays; +import java.util.Collection; +import java.util.Comparator; +import java.util.stream.Collectors; + +/** + * YAML rule configuration reflection engine. + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class YamlRuleConfigurationReflectionEngine { + + /** + * Find YAML rule configuration class. + * + * @param ruleType rule type + * @return found class + * @throws IllegalArgumentException throw if YAML rule configuration class not found + */ + @SuppressWarnings("rawtypes") + public static Class<? extends YamlRuleConfiguration> findClass(final String ruleType) { + for (YamlRuleConfigurationSwapper each : ShardingSphereServiceLoader.getServiceInstances(YamlRuleConfigurationSwapper.class)) { + Class<? extends YamlRuleConfiguration> yamlRuleConfigClass = getYamlRuleConfigurationClass(each); + RuleNodeTupleEntity entity = yamlRuleConfigClass.getAnnotation(RuleNodeTupleEntity.class); + if (null != entity && entity.value().equals(ruleType)) { + return yamlRuleConfigClass; + } + } + throw new IllegalArgumentException(String.format("Can not find YAML rule configuration with type: %s", ruleType)); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + private static Class<? extends YamlRuleConfiguration> getYamlRuleConfigurationClass(final YamlRuleConfigurationSwapper swapper) { + return (Class<? extends YamlRuleConfiguration>) ((ParameterizedType) swapper.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; + } + + /** + * Get YAML rule configuration fields. + * + * @param yamlRuleConfigClass YAML rule configuration class + * @return got fields + */ + public static Collection<Field> getFields(final Class<? extends YamlRuleConfiguration> yamlRuleConfigClass) { + return Arrays.stream(yamlRuleConfigClass.getDeclaredFields()) + .filter(each -> null != each.getAnnotation(RuleNodeTupleField.class)) + .sorted(Comparator.comparingInt(o -> o.getAnnotation(RuleNodeTupleField.class).type().ordinal())).collect(Collectors.toList()); + } + + /** + * Get rule node item name. + * + * @param field YAML rule configuration field + * @return got name + */ + public static String getRuleNodeItemName(final Field field) { + return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()); + } +} diff --git a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleNodeTupleSwapperEngine.java b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleNodeTupleSwapperEngine.java index 45bba6df9b4..6e0d2a6332c 100644 --- a/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleNodeTupleSwapperEngine.java +++ b/mode/node/src/main/java/org/apache/shardingsphere/mode/node/rule/tuple/YamlRuleNodeTupleSwapperEngine.java @@ -20,11 +20,9 @@ package org.apache.shardingsphere.mode.node.rule.tuple; import com.google.common.base.Preconditions; import com.google.common.base.Strings; import lombok.SneakyThrows; -import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader; import org.apache.shardingsphere.infra.util.yaml.YamlEngine; import org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlGlobalRuleConfiguration; import org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlRuleConfiguration; -import org.apache.shardingsphere.infra.yaml.config.swapper.rule.YamlRuleConfigurationSwapper; import org.apache.shardingsphere.mode.node.path.engine.searcher.NodePathPattern; import org.apache.shardingsphere.mode.node.path.engine.searcher.NodePathSearchCriteria; import org.apache.shardingsphere.mode.node.path.engine.searcher.NodePathSearcher; @@ -78,7 +76,7 @@ public final class YamlRuleNodeTupleSwapperEngine { Preconditions.checkArgument(!entity.leaf()); String ruleType = entity.value(); Collection<RuleNodeTuple> result = new LinkedList<>(); - for (Field each : YamlRuleConfigurationFieldUtil.getFields(yamlRuleConfig.getClass())) { + for (Field each : YamlRuleConfigurationReflectionEngine.getFields(yamlRuleConfig.getClass())) { boolean isAccessible = each.isAccessible(); each.setAccessible(true); result.addAll(swapToTuples(databaseName, ruleType, yamlRuleConfig, each)); @@ -93,7 +91,7 @@ public final class YamlRuleNodeTupleSwapperEngine { if (null == fieldValue) { return Collections.emptyList(); } - String tupleName = YamlRuleConfigurationFieldUtil.getTupleItemName(field); + String tupleName = YamlRuleConfigurationReflectionEngine.getRuleNodeItemName(field); return isNamedItem(field) ? swapToNamedTuples(databaseName, ruleType, tupleName, field, fieldValue) : swapToUniqueTuple(databaseName, ruleType, tupleName, fieldValue).map(Collections::singletonList).orElse(Collections.emptyList()); @@ -106,8 +104,7 @@ public final class YamlRuleNodeTupleSwapperEngine { if (fieldValue instanceof Map) { for (Object entry : ((Map) fieldValue).entrySet()) { String ruleItemName = ((Entry) entry).getKey().toString(); - result.add( - new RuleNodeTuple(new DatabaseRuleNodePath(databaseName, ruleType, new DatabaseRuleItem(ruleItemType, ruleItemName)), YamlEngine.marshal(((Entry) entry).getValue()))); + result.add(new RuleNodeTuple(new DatabaseRuleNodePath(databaseName, ruleType, new DatabaseRuleItem(ruleItemType, ruleItemName)), YamlEngine.marshal(((Entry) entry).getValue()))); } } else { for (Object each : (Collection) fieldValue) { @@ -142,18 +139,9 @@ public final class YamlRuleNodeTupleSwapperEngine { * @param ruleType rule type * @param ruleContent rule content * @return global rule configuration - * @throws IllegalArgumentException throw if rule configuration not found */ - @SuppressWarnings("rawtypes") public YamlRuleConfiguration swapToYamlGlobalRuleConfiguration(final String ruleType, final String ruleContent) { - for (YamlRuleConfigurationSwapper each : OrderedSPILoader.getServices(YamlRuleConfigurationSwapper.class)) { - Class<? extends YamlRuleConfiguration> yamlRuleConfigClass = getYamlRuleConfigurationClass(each); - RuleNodeTupleEntity entity = yamlRuleConfigClass.getAnnotation(RuleNodeTupleEntity.class); - if (null != entity && ruleType.equals(entity.value())) { - return YamlEngine.unmarshal(ruleContent, yamlRuleConfigClass); - } - } - throw new IllegalArgumentException(String.format("Can not find rule configuration with type: %s", ruleType)); + return YamlEngine.unmarshal(ruleContent, YamlRuleConfigurationReflectionEngine.findClass(ruleType)); } /** @@ -163,33 +151,19 @@ public final class YamlRuleNodeTupleSwapperEngine { * @param ruleType rule type * @param tuples rule node tuples * @return database rule configuration - * @throws IllegalArgumentException throw if rule configuration not found */ - @SuppressWarnings("rawtypes") - public YamlRuleConfiguration swapToYamlDatabaseRuleConfiguration(final String databaseName, final String ruleType, final Collection<RuleNodeTuple> tuples) { - for (YamlRuleConfigurationSwapper each : OrderedSPILoader.getServices(YamlRuleConfigurationSwapper.class)) { - Class<? extends YamlRuleConfiguration> yamlRuleConfigClass = getYamlRuleConfigurationClass(each); - RuleNodeTupleEntity entity = yamlRuleConfigClass.getAnnotation(RuleNodeTupleEntity.class); - if (null != entity && entity.value().equals(ruleType)) { - return swapToYamlDatabaseRuleConfiguration(databaseName, yamlRuleConfigClass, tuples) - .orElseThrow(() -> new IllegalArgumentException(String.format("Can not find rule configuration with type: %s", ruleType))); - } - } - throw new IllegalArgumentException(String.format("Can not find rule configuration with type: %s", ruleType)); - } - @SneakyThrows(ReflectiveOperationException.class) - private Optional<YamlRuleConfiguration> swapToYamlDatabaseRuleConfiguration(final String databaseName, - final Class<? extends YamlRuleConfiguration> toBeSwappedType, final Collection<RuleNodeTuple> tuples) { - Collection<Field> fields = YamlRuleConfigurationFieldUtil.getFields(toBeSwappedType); - YamlRuleConfiguration yamlRuleConfig = toBeSwappedType.getConstructor().newInstance(); - DatabaseRuleNode databaseRuleNode = DatabaseRuleNodeGenerator.generate(toBeSwappedType); + public YamlRuleConfiguration swapToYamlDatabaseRuleConfiguration(final String databaseName, final String ruleType, final Collection<RuleNodeTuple> tuples) { + Class<? extends YamlRuleConfiguration> yamlRuleConfigClass = YamlRuleConfigurationReflectionEngine.findClass(ruleType); + Collection<Field> fields = YamlRuleConfigurationReflectionEngine.getFields(yamlRuleConfigClass); + YamlRuleConfiguration result = yamlRuleConfigClass.getConstructor().newInstance(); + DatabaseRuleNode databaseRuleNode = DatabaseRuleNodeGenerator.generate(yamlRuleConfigClass); for (RuleNodeTuple each : tuples) { if (!Strings.isNullOrEmpty(each.getContent())) { - setFieldValue(databaseName, yamlRuleConfig, fields, databaseRuleNode.getRuleType(), each); + setFieldValue(databaseName, result, fields, databaseRuleNode.getRuleType(), each); } } - return Optional.of(yamlRuleConfig); + return result; } private void setFieldValue(final String databaseName, final YamlRuleConfiguration yamlRuleConfig, final Collection<Field> fields, final String ruleType, final RuleNodeTuple tuple) { @@ -201,9 +175,8 @@ public final class YamlRuleNodeTupleSwapperEngine { } } - private void setFieldValue(final String databaseName, final YamlRuleConfiguration yamlRuleConfig, - final Field field, final String ruleType, final RuleNodeTuple tuple) { - String itemType = YamlRuleConfigurationFieldUtil.getTupleItemName(field); + private void setFieldValue(final String databaseName, final YamlRuleConfiguration yamlRuleConfig, final Field field, final String ruleType, final RuleNodeTuple tuple) { + String itemType = YamlRuleConfigurationReflectionEngine.getRuleNodeItemName(field); if (isNamedItem(field)) { setNamedItemFieldValue(databaseName, yamlRuleConfig, ruleType, tuple, itemType, field); } else { @@ -262,9 +235,4 @@ public final class YamlRuleNodeTupleSwapperEngine { field.set(yamlRuleConfig, YamlEngine.unmarshal(tuple.getContent(), field.getType())); } } - - @SuppressWarnings({"unchecked", "rawtypes"}) - private Class<? extends YamlRuleConfiguration> getYamlRuleConfigurationClass(final YamlRuleConfigurationSwapper swapper) { - return (Class<? extends YamlRuleConfiguration>) ((ParameterizedType) swapper.getClass().getGenericInterfaces()[0]).getActualTypeArguments()[0]; - } }