X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fyang-binding%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fyangtools%2Fyang%2Fbinding%2Fcontract%2FNaming.java;h=ccedb54c957da8f9179b97856604a8d37ee60537;hb=2dc68c7487457235e0271766bc4aad878c82ca15;hp=1f94a6c9272f24a5f6aaa52030464a771254b559;hpb=2a1eb5ac8c50bafffc73fa656a5125bfb85871dc;p=mdsal.git diff --git a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/contract/Naming.java b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/contract/Naming.java index 1f94a6c927..ccedb54c95 100644 --- a/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/contract/Naming.java +++ b/binding/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/contract/Naming.java @@ -8,6 +8,7 @@ package org.opendaylight.yangtools.yang.binding.contract; import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Verify.verify; import static java.util.Objects.requireNonNull; import com.google.common.annotations.Beta; @@ -20,7 +21,6 @@ import com.google.common.collect.Interner; import com.google.common.collect.Interners; import java.util.Collection; import java.util.Locale; -import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.checkerframework.checker.regex.qual.Regex; @@ -28,14 +28,13 @@ import org.eclipse.jdt.annotation.NonNull; import org.opendaylight.yangtools.yang.binding.Action; import org.opendaylight.yangtools.yang.binding.Augmentable; import org.opendaylight.yangtools.yang.binding.BindingContract; -import org.opendaylight.yangtools.yang.binding.Identifiable; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyAware; import org.opendaylight.yangtools.yang.binding.Rpc; import org.opendaylight.yangtools.yang.binding.RpcInput; import org.opendaylight.yangtools.yang.binding.ScalarTypeObject; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.QNameModule; -import org.opendaylight.yangtools.yang.common.Revision; import org.opendaylight.yangtools.yang.common.YangDataName; @Beta @@ -65,10 +64,6 @@ public final class Naming { "record"); public static final @NonNull String DATA_ROOT_SUFFIX = "Data"; - @Deprecated(since = "11.0.0", forRemoval = true) - public static final @NonNull String RPC_SERVICE_SUFFIX = "Service"; - @Deprecated(since = "10.0.3", forRemoval = true) - public static final @NonNull String NOTIFICATION_LISTENER_SUFFIX = "Listener"; public static final @NonNull String BUILDER_SUFFIX = "Builder"; public static final @NonNull String KEY_SUFFIX = "Key"; // ietf-restconf:yang-data, i.e. YangDataName @@ -78,6 +73,7 @@ public final class Naming { // concrete extensible contracts, for example 'feature', 'identity' and similar public static final @NonNull String VALUE_STATIC_FIELD_NAME = "VALUE"; public static final @NonNull String PACKAGE_PREFIX = "org.opendaylight.yang.gen.v1"; + public static final @NonNull String SVC_PACKAGE_PREFIX = "org.opendaylight.yang.svc.v1"; public static final @NonNull String AUGMENTATION_FIELD = "augmentation"; private static final Splitter CAMEL_SPLITTER = Splitter.on(CharMatcher.anyOf(" _.-/").precomputed()) @@ -86,10 +82,10 @@ public final class Naming { private static final String QUOTED_DOT = Matcher.quoteReplacement("."); private static final Splitter DOT_SPLITTER = Splitter.on('.'); - public static final @NonNull String MODULE_INFO_CLASS_NAME = "$YangModuleInfoImpl"; + public static final @NonNull String MODULE_INFO_CLASS_NAME = "YangModuleInfoImpl"; public static final @NonNull String MODULE_INFO_QNAMEOF_METHOD_NAME = "qnameOf"; public static final @NonNull String MODULE_INFO_YANGDATANAMEOF_METHOD_NAME = "yangDataNameOf"; - public static final @NonNull String MODEL_BINDING_PROVIDER_CLASS_NAME = "$YangModelBindingProvider"; + public static final @NonNull String MODEL_BINDING_PROVIDER_CLASS_NAME = "YangModelBindingProviderImpl"; /** * Name of {@link Augmentable#augmentation(Class)}. @@ -97,9 +93,9 @@ public final class Naming { public static final @NonNull String AUGMENTABLE_AUGMENTATION_NAME = "augmentation"; /** - * Name of {@link Identifiable#key()}. + * Name of {@link KeyAware#key()}. */ - public static final @NonNull String IDENTIFIABLE_KEY_NAME = "key"; + public static final @NonNull String KEY_AWARE_KEY_NAME = "key"; /** * Name of {@link BindingContract#implementedInterface()}. @@ -160,21 +156,36 @@ public final class Naming { private static final Interner PACKAGE_INTERNER = Interners.newWeakInterner(); @Regex private static final String ROOT_PACKAGE_PATTERN_STRING = - "(org.opendaylight.yang.gen.v1.[a-z0-9_\\.]*?\\.(?:rev[0-9][0-9][0-1][0-9][0-3][0-9]|norev))"; + "(org.opendaylight.yang.(gen|svc).v1.[a-z0-9_\\.]*?\\.(?:rev[0-9][0-9][0-1][0-9][0-3][0-9]|norev))"; private static final Pattern ROOT_PACKAGE_PATTERN = Pattern.compile(ROOT_PACKAGE_PATTERN_STRING); private Naming() { // Hidden on purpose } + /** + * Return the package name for placing generated ServiceLoader entities, like {@link #MODULE_INFO_CLASS_NAME} and + * {@link #MODEL_BINDING_PROVIDER_CLASS_NAME}. + * + * @param module module namespace + * @return the package name for placing generated ServiceLoader entities + */ + public static @NonNull String getServicePackageName(final QNameModule module) { + final StringBuilder packageNameBuilder = new StringBuilder().append(SVC_PACKAGE_PREFIX).append('.'); + return getRootPackageName(packageNameBuilder, module); + } + public static @NonNull String getRootPackageName(final QName module) { return getRootPackageName(module.getModule()); } public static @NonNull String getRootPackageName(final QNameModule module) { final StringBuilder packageNameBuilder = new StringBuilder().append(PACKAGE_PREFIX).append('.'); + return getRootPackageName(packageNameBuilder, module); + } - String namespace = module.getNamespace().toString(); + private static @NonNull String getRootPackageName(final StringBuilder builder, final QNameModule module) { + String namespace = module.namespace().toString(); namespace = COLON_SLASH_SLASH.matcher(namespace).replaceAll(QUOTED_DOT); final char[] chars = namespace.toCharArray(); @@ -187,24 +198,38 @@ public final class Naming { } } - packageNameBuilder.append(chars); + builder.append(chars); if (chars[chars.length - 1] != '.') { - packageNameBuilder.append('.'); + builder.append('.'); } - final Optional optRev = module.getRevision(); - if (optRev.isPresent()) { + final var revision = module.revision(); + if (revision != null) { // Revision is in format 2017-10-26, we want the output to be 171026, which is a matter of picking the // right characters. - final String rev = optRev.orElseThrow().toString(); - checkArgument(rev.length() == 10, "Unsupported revision %s", rev); - packageNameBuilder.append("rev").append(rev, 2, 4).append(rev, 5, 7).append(rev.substring(8)); + final String rev = revision.toString(); + verify(rev.length() == 10, "Revision.toString() resulted in unexpected '%s'", rev); + builder.append("rev").append(rev, 2, 4).append(rev, 5, 7).append(rev.substring(8)); } else { // No-revision packages are special - packageNameBuilder.append("norev"); + builder.append("norev"); } - return normalizePackageName(packageNameBuilder.toString()); + return normalizePackageName(builder.toString()); + } + + /** + * Convert the result of {@link #getRootPackageName(QNameModule)} to the corresponding result of + * {@link #getServicePackageName(QNameModule)}. + * + * @param rootPackageName root package name + * @return Service root package name + */ + public static @NonNull String rootToServicePackageName(final String rootPackageName) { + final var match = ROOT_PACKAGE_PATTERN.matcher(rootPackageName); + checkArgument(match.find(), "Package name '%s' does not match required pattern '%s'", rootPackageName, + ROOT_PACKAGE_PATTERN_STRING); + return getModelRootPackageName(rootPackageName.replace(Naming.PACKAGE_PREFIX, Naming.SVC_PACKAGE_PREFIX)); } public static @NonNull String normalizePackageName(final String packageName) { @@ -358,18 +383,6 @@ public final class Naming { return str.substring(0, 1).toLowerCase(Locale.ENGLISH) + str.substring(1); } - /** - * Returns the {@link String} {@code s} with a '$' character as suffix. - * - * @param qname RPC QName - * @return The RPC method name as determined by considering the localname against the JLS. - * @throws NullPointerException if {@code qname} is null - */ - public static @NonNull String getRpcMethodName(final @NonNull QName qname) { - final String methodName = getMethodName(qname); - return JAVA_RESERVED_WORDS.contains(methodName) ? methodName + "$" : methodName; - } - /** * Returns root package name for supplied package name. * @@ -380,8 +393,8 @@ public final class Naming { * not match package name formatting rules */ public static @NonNull String getModelRootPackageName(final String packageName) { - checkArgument(packageName.startsWith(PACKAGE_PREFIX), "Package name not starting with %s, is: %s", - PACKAGE_PREFIX, packageName); + checkArgument(packageName.startsWith(PACKAGE_PREFIX) || packageName.startsWith(SVC_PACKAGE_PREFIX), + "Package name not starting with %s, is: %s", PACKAGE_PREFIX, packageName); final var match = ROOT_PACKAGE_PATTERN.matcher(packageName); checkArgument(match.find(), "Package name '%s' does not match required pattern '%s'", packageName, ROOT_PACKAGE_PATTERN_STRING);