X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=binding%2Fmdsal-binding-java-api-generator%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fmdsal%2Fbinding%2Fjava%2Fapi%2Fgenerator%2FAbstractJavaGeneratedType.java;h=63ecbd0dd1a809f2e870bdb9a30586fed5e14906;hb=refs%2Fchanges%2F14%2F100114%2F1;hp=607451b650161a17fec4a0c6b2989a6704f9071c;hpb=a88b2224bbb374e1512b1dc538ab8a7f6cb3b737;p=mdsal.git diff --git a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/AbstractJavaGeneratedType.java b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/AbstractJavaGeneratedType.java index 607451b650..63ecbd0dd1 100644 --- a/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/AbstractJavaGeneratedType.java +++ b/binding/mdsal-binding-java-api-generator/src/main/java/org/opendaylight/mdsal/binding/java/api/generator/AbstractJavaGeneratedType.java @@ -7,18 +7,17 @@ */ package org.opendaylight.mdsal.binding.java.api.generator; -import static com.google.common.collect.ImmutableSet.toImmutableSet; import static java.util.Objects.requireNonNull; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; -import com.google.common.collect.Streams; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; import java.util.Set; -import javax.annotation.concurrent.NotThreadSafe; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.opendaylight.mdsal.binding.model.api.Enumeration; @@ -31,16 +30,15 @@ import org.opendaylight.mdsal.binding.model.api.WildcardType; /** * Abstract class representing a generated type, either top-level or nested. It takes care of tracking references - * to other Java types and resolving them as best as possible. + * to other Java types and resolving them as best as possible. This class is NOT thread-safe. * * @author Robert Varga */ @NonNullByDefault -@NotThreadSafe abstract class AbstractJavaGeneratedType { private final Map nameCache = new HashMap<>(); - private final Map enclosedTypes; - private final Set conflictingNames; + private final ImmutableMap enclosedTypes; + private final ImmutableSet conflictingNames; private final JavaTypeName name; @@ -51,20 +49,27 @@ abstract class AbstractJavaGeneratedType { b.put(type.getIdentifier().simpleName(), new NestedJavaGeneratedType(this, type)); } enclosedTypes = b.build(); - conflictingNames = genType instanceof Enumeration - ? ((Enumeration) genType).getValues().stream().map(Pair::getMappedName).collect(toImmutableSet()) - : ImmutableSet.of(); - } - AbstractJavaGeneratedType(final JavaTypeName name, final GeneratedType genType) { - this.name = requireNonNull(name); - enclosedTypes = ImmutableMap.of(); + final Set cb = new HashSet<>(); + if (genType instanceof Enumeration) { + ((Enumeration) genType).getValues().stream().map(Pair::getMappedName).forEach(cb::add); + } + // TODO: perhaps we can do something smarter to actually access the types + collectAccessibleTypes(cb, genType); + + conflictingNames = ImmutableSet.copyOf(cb); + } - // This is a workaround for BuilderTemplate, which does not model itself correctly -- it should generate - // a GeneratedType for the Builder with a nested type for the implementation, which really should be - // a different template which gets generated as an inner type. - conflictingNames = Streams.concat(genType.getEnclosedTypes().stream(), genType.getEnumerations().stream()) - .map(type -> type.getIdentifier().simpleName()).collect(toImmutableSet()); + private void collectAccessibleTypes(final Set set, final GeneratedType type) { + for (Type impl : type.getImplements()) { + if (impl instanceof GeneratedType) { + final GeneratedType genType = (GeneratedType) impl; + for (GeneratedType inner : Iterables.concat(genType.getEnclosedTypes(), genType.getEnumerations())) { + set.add(inner.getIdentifier().simpleName()); + } + collectAccessibleTypes(set, genType); + } + } } final JavaTypeName getName() { @@ -75,29 +80,48 @@ abstract class AbstractJavaGeneratedType { return name.simpleName(); } - final String getReferenceString(final Type type) { - if (!(type instanceof ParameterizedType)) { - return getReferenceString(type.getIdentifier()); + private String annotateReference(final String ref, final Type type, final String annotation) { + if (type instanceof ParameterizedType) { + return getReferenceString(annotate(ref, annotation), type, + ((ParameterizedType) type).getActualTypeArguments()); } + return "byte[]".equals(ref) ? "byte @" + annotation + "[]" : annotate(ref, annotation).toString(); + } - final StringBuilder sb = new StringBuilder(); - sb.append(getReferenceString(type.getIdentifier())).append('<'); - final Type[] types = ((ParameterizedType) type).getActualTypeArguments(); - if (types.length == 0) { - return sb.append("?>").toString(); + final String getFullyQualifiedReference(final Type type, final String annotation) { + return annotateReference(type.getFullyQualifiedName(), type ,annotation); + } + + final String getReferenceString(final Type type) { + final String ref = getReferenceString(type.getIdentifier()); + return type instanceof ParameterizedType ? getReferenceString(new StringBuilder(ref), type, + ((ParameterizedType) type).getActualTypeArguments()) + : ref; + } + + final String getReferenceString(final Type type, final String annotation) { + // Package-private method, all callers who would be passing an empty array are bound to the more special + // case above, hence we know annotations.length >= 1 + final String ref = getReferenceString(type.getIdentifier()); + return annotateReference(ref, type, annotation); + } + + private String getReferenceString(final StringBuilder sb, final Type type, final @NonNull Type[] arguments) { + if (arguments.length == 0) { + return sb.append("").toString(); } - for (int i = 0; i < types.length; i++) { - final Type t = types[i]; - if (t instanceof WildcardType) { + sb.append('<'); + for (int i = 0; i < arguments.length; i++) { + final Type arg = arguments[i]; + if (arg instanceof WildcardType) { sb.append("? extends "); } - sb.append(getReferenceString(t)); - if (i != types.length - 1) { + sb.append(getReferenceString(arg)); + if (i != arguments.length - 1) { sb.append(", "); } } - return sb.append('>').toString(); } @@ -155,4 +179,13 @@ abstract class AbstractJavaGeneratedType { // Try to anchor the top-level type and use a local reference return checkAndImportType(type.topLevelClass()) ? type.localName() : type.toString(); } + + private static StringBuilder annotate(final String ref, final String annotation) { + final StringBuilder sb = new StringBuilder(); + final int dot = ref.lastIndexOf('.'); + if (dot != -1) { + sb.append(ref, 0, dot + 1); + } + return sb.append('@').append(annotation).append(' ').append(ref, dot + 1, ref.length()); + } }