Update TypeDefinition design
[yangtools.git] / yang / yang-model-util / src / main / java / org / opendaylight / yangtools / yang / model / util / type / DerivedTypeBuilder.java
index 5110f530af7e1a141824d1f8a32fff70b13f4200..943ede440365495877045ba4380d9eade7bfafb6 100644 (file)
@@ -7,11 +7,16 @@
  */
 package org.opendaylight.yangtools.yang.model.util.type;
 
-import com.google.common.base.Preconditions;
+import static com.google.common.base.Preconditions.checkArgument;
+import static java.util.Objects.requireNonNull;
+
+import java.util.Optional;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.Status;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * Builder of {@link TypeDefinitions} for use in typedef statements.
@@ -19,6 +24,7 @@ import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
  * @param <T> Resulting {@link TypeDefinition}
  */
 public abstract class DerivedTypeBuilder<T extends TypeDefinition<T>> extends TypeBuilder<T> {
+    private static final Logger LOG = LoggerFactory.getLogger(DecimalTypeBuilder.class);
     private Object defaultValue;
     private String description;
     private String reference;
@@ -26,27 +32,44 @@ public abstract class DerivedTypeBuilder<T extends TypeDefinition<T>> extends Ty
     private String units;
 
     DerivedTypeBuilder(final T baseType, final SchemaPath path) {
-        super(Preconditions.checkNotNull(baseType), path);
+        super(requireNonNull(baseType), path);
+
+        checkArgument(baseType instanceof AbstractBaseType || baseType instanceof AbstractDerivedType
+            || baseType instanceof AbstractRestrictedType,
+            "Derived type can be built only from a base, derived, or restricted type, not %s", baseType);
+
+        // http://tools.ietf.org/html/rfc6020#section-7.3.4
+        defaultValue = baseType.getDefaultValue().orElse(null);
+
+        // In similar vein, it makes sense to propagate units
+        units = baseType.getUnits().orElse(null);
     }
 
     public void setDefaultValue(@Nonnull final Object defaultValue) {
-        this.defaultValue = Preconditions.checkNotNull(defaultValue);
+        this.defaultValue = requireNonNull(defaultValue);
     }
 
     public final void setDescription(@Nonnull final String description) {
-        this.description = Preconditions.checkNotNull(description);
+        this.description = requireNonNull(description);
     }
 
     public final void setReference(@Nonnull final String reference) {
-        this.reference = Preconditions.checkNotNull(reference);
+        this.reference = requireNonNull(reference);
     }
 
     public final void setStatus(@Nonnull final Status status) {
-        this.status = Preconditions.checkNotNull(status);
+        this.status = requireNonNull(status);
     }
 
     public final void setUnits(final String units) {
-        this.units = Preconditions.checkNotNull(units);
+        requireNonNull(units);
+
+        final Optional<String> baseUnits = getBaseType().getUnits();
+        if (baseUnits.isPresent() && !units.equals(baseUnits.get())) {
+            LOG.warn("Type {} uverrides 'units' of type {} to \"{}\"", getPath(), getBaseType(), units);
+        }
+
+        this.units = units;
     }
 
     final Object getDefaultValue() {
@@ -68,4 +91,4 @@ public abstract class DerivedTypeBuilder<T extends TypeDefinition<T>> extends Ty
     final String getUnits() {
         return units;
     }
-}
\ No newline at end of file
+}