Specialize JavaFileTemplate.importedName(Type)
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / main / java / org / opendaylight / mdsal / binding / java / api / generator / JavaFileTemplate.java
index 67e2b6b4e8a5c484a4dfd59c6ff9746a6f426798..58282d64e275cc6dc1ea7ae0ef110f2d05e7f0fd 100644 (file)
@@ -7,10 +7,11 @@
  */
 package org.opendaylight.mdsal.binding.java.api.generator;
 
+import static com.google.common.base.Verify.verify;
 import static java.util.Objects.requireNonNull;
 
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Arrays;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.stream.Collectors;
 import org.opendaylight.mdsal.binding.model.api.ConcreteType;
@@ -26,15 +27,29 @@ import org.opendaylight.mdsal.binding.model.util.Types;
  * Base Java file template. Contains a non-null type and imports which the generated code refers to.
  */
 class JavaFileTemplate {
-    // Hidden to well-define operations
-    private final Map<String, JavaTypeName> importMap = new HashMap<>();
+    static final JavaTypeName NONNULL = JavaTypeName.create("org.eclipse.jdt.annotation", "NonNull");
+    static final JavaTypeName NULLABLE = JavaTypeName.create("org.eclipse.jdt.annotation", "Nullable");
 
-    protected final GeneratedType type;
+    private final AbstractJavaGeneratedType javaType;
+    private final GeneratedType type;
 
     JavaFileTemplate(final GeneratedType type) {
+        this(new TopLevelJavaGeneratedType(type), type);
+    }
+
+    JavaFileTemplate(final AbstractJavaGeneratedType javaType, final GeneratedType type) {
+        this.javaType = requireNonNull(javaType);
         this.type = requireNonNull(type);
     }
 
+    final AbstractJavaGeneratedType javaType() {
+        return javaType;
+    }
+
+    final GeneratedType type() {
+        return type;
+    }
+
     final GeneratedProperty findProperty(final GeneratedTransferObject gto, final String name) {
         final Optional<GeneratedProperty> optProp = gto.getProperties().stream()
                 .filter(prop -> prop.getName().equals(name)).findFirst();
@@ -46,42 +61,38 @@ class JavaFileTemplate {
         return parent != null ? findProperty(parent, name) : null;
     }
 
-    static final Restrictions getRestrictions(final Type type) {
-        if (type instanceof ConcreteType) {
-            return ((ConcreteType)type).getRestrictions();
-        }
-        if (type instanceof GeneratedTransferObject) {
-            return ((GeneratedTransferObject)type).getRestrictions();
-        }
-        return null;
-    }
-
     final String generateImportBlock() {
-        return importMap.entrySet().stream()
-                .filter(e -> isDefaultVisible(e.getValue()))
-                .sorted((e1, e2) -> {
-                    return e1.getValue().toString().compareTo(e2.getValue().toString());
-                })
-                .map(e -> "import " + e.getValue() + ";\n")
+        verify(javaType instanceof TopLevelJavaGeneratedType);
+        return ((TopLevelJavaGeneratedType) javaType).imports().map(name -> "import " + name + ";\n")
                 .collect(Collectors.joining());
     }
 
     final String importedName(final Type intype) {
-        GeneratorUtil.putTypeIntoImports(type, intype, importMap);
-        return GeneratorUtil.getExplicitType(type, intype, importMap);
+        return javaType.getReferenceString(intype);
+    }
+
+    final String importedName(final Type intype, final String... annotations) {
+        return javaType.getReferenceString(intype, annotations);
     }
 
     final String importedName(final Class<?> cls) {
         return importedName(Types.typeForClass(cls));
     }
 
-    final void addImport(final Class<?> cls) {
-        final JavaTypeName name = JavaTypeName.create(cls);
-        importMap.put(name.simpleName(), name);
+    final String importedName(final JavaTypeName intype) {
+        return javaType.getReferenceString(intype);
     }
 
-    final void addImports(final JavaFileTemplate from) {
-        importMap.putAll(from.importMap);
+    final String importedNonNull(final Type intype) {
+        return importedName(intype, importedName(NONNULL));
+    }
+
+    final String importedNullable(final Type intype) {
+        return importedName(intype, importedName(NULLABLE));
+    }
+
+    final void addImport(final Class<?> cls) {
+        javaType.getReferenceString(JavaTypeName.create(cls));
     }
 
     // Exposed for BuilderTemplate
@@ -90,17 +101,39 @@ class JavaFileTemplate {
         return optEnc.isPresent() && type.getIdentifier().equals(optEnc.get());
     }
 
-    private boolean isDefaultVisible(final JavaTypeName name) {
-        return !hasSamePackage(name) || !isLocalInnerClass(name);
+    final CharSequence generateInnerClass(final GeneratedType innerClass) {
+        if (!(innerClass instanceof GeneratedTransferObject)) {
+            return "";
+        }
+
+        final GeneratedTransferObject gto = (GeneratedTransferObject) innerClass;
+        final NestedJavaGeneratedType innerJavaType = javaType.getEnclosedType(innerClass.getIdentifier());
+        return gto.isUnionType() ? new UnionTemplate(innerJavaType, gto).generateAsInnerClass()
+                : new ClassTemplate(innerJavaType, gto).generateAsInnerClass();
     }
 
     /**
-     * Checks if packages of generated type and imported type is the same
+     * Return imported name of java.util class, whose hashCode/equals methods we want to invoke on the property. Returns
+     * {@link Arrays} if the property is an array, {@link Objects} otherwise.
      *
-     * @param importedTypePackageName the package name of imported type
-     * @return true if the packages are the same false otherwise
+     * @param property Generated property
+     * @return Imported class name
      */
-    private boolean hasSamePackage(final JavaTypeName name) {
-        return type.getPackageName().equals(name.packageName());
+    final String importedUtilClass(final GeneratedProperty property) {
+        return importedName(property.getReturnType().getName().indexOf('[') != -1 ? Arrays.class : Objects.class);
+    }
+
+    static final Restrictions restrictionsForSetter(final Type actualType) {
+        return actualType instanceof GeneratedType ? null : getRestrictions(actualType);
+    }
+
+    static final Restrictions getRestrictions(final Type type) {
+        if (type instanceof ConcreteType) {
+            return ((ConcreteType) type).getRestrictions();
+        }
+        if (type instanceof GeneratedTransferObject) {
+            return ((GeneratedTransferObject) type).getRestrictions();
+        }
+        return null;
     }
 }