All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.elibracha.compare.schemadiffresult.ComposedSchemaDiffResult Maven / Gradle / Ivy

There is a newer version: 2.3.6
Show newest version
package com.github.elibracha.compare.schemadiffresult;

import com.github.elibracha.compare.MapKeyDiff;
import com.github.elibracha.compare.OpenApiDiff;
import com.github.elibracha.model.ChangedOneOfSchema;
import com.github.elibracha.model.ChangedSchema;
import com.github.elibracha.model.DiffContext;
import com.github.elibracha.utils.RefPointer;
import com.github.elibracha.utils.RefType;

import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.media.ComposedSchema;
import io.swagger.v3.oas.models.media.Discriminator;
import io.swagger.v3.oas.models.media.Schema;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import org.apache.commons.collections4.CollectionUtils;

/** Created by adarsh.sharma on 20/12/17. */
public class ComposedSchemaDiffResult extends SchemaDiffResult {
  private static RefPointer refPointer = new RefPointer<>(RefType.SCHEMAS);

  public ComposedSchemaDiffResult(OpenApiDiff openApiDiff) {
    super(openApiDiff);
  }

  @Override
  public , X> Optional diff(
      HashSet refSet,
      Components leftComponents,
      Components rightComponents,
      T left,
      T right,
      DiffContext context) {
    if (left instanceof ComposedSchema) {
      ComposedSchema leftComposedSchema = (ComposedSchema) left;
      ComposedSchema rightComposedSchema = (ComposedSchema) right;
      if (CollectionUtils.isNotEmpty(leftComposedSchema.getOneOf())
          || CollectionUtils.isNotEmpty(rightComposedSchema.getOneOf())) {

        Discriminator leftDis = leftComposedSchema.getDiscriminator();
        Discriminator rightDis = rightComposedSchema.getDiscriminator();
        if (leftDis == null
            || rightDis == null
            || leftDis.getPropertyName() == null
            || rightDis.getPropertyName() == null) {
          throw new IllegalArgumentException(
              "discriminator or property not found for oneOf schema");
        } else if (!leftDis.getPropertyName().equals(rightDis.getPropertyName())
            || (CollectionUtils.isEmpty(leftComposedSchema.getOneOf())
                || CollectionUtils.isEmpty(rightComposedSchema.getOneOf()))) {
          changedSchema.setOldSchema(left);
          changedSchema.setNewSchema(right);
          changedSchema.setDiscriminatorPropertyChanged(true);
          changedSchema.setContext(context);
          return Optional.of(changedSchema);
        }

        Map leftMapping = getMapping(leftComposedSchema);
        Map rightMapping = getMapping(rightComposedSchema);

        MapKeyDiff mappingDiff =
            MapKeyDiff.diff(
                getSchema(leftComponents, leftMapping), getSchema(rightComponents, rightMapping));
        Map changedMapping = new LinkedHashMap<>();
        for (String key : mappingDiff.getSharedKey()) {
          Schema leftSchema = new Schema();
          leftSchema.set$ref(leftMapping.get(key));
          Schema rightSchema = new Schema();
          rightSchema.set$ref(rightMapping.get(key));
          Optional changedSchema =
              openApiDiff
                  .getSchemaDiff()
                  .diff(refSet, leftSchema, rightSchema, context.copyWithRequired(true));
          changedSchema.ifPresent(schema -> changedMapping.put(key, schema));
        }
        changedSchema.setOneOfSchema(
            new ChangedOneOfSchema(leftMapping, rightMapping, context)
                .setIncreased(mappingDiff.getIncreased())
                .setMissing(mappingDiff.getMissing())
                .setChanged(changedMapping));
      }
      return super.diff(refSet, leftComponents, rightComponents, left, right, context);
    } else {
      return openApiDiff.getSchemaDiff().getTypeChangedSchema(left, right, context);
    }
  }

  private Map getSchema(Components components, Map mapping) {
    Map result = new LinkedHashMap<>();
    mapping.forEach(
        (key, value) -> result.put(key, refPointer.resolveRef(components, new Schema(), value)));
    return result;
  }

  private Map getMapping(ComposedSchema composedSchema) {
    Map reverseMapping = new LinkedHashMap<>();
    for (Schema schema : composedSchema.getOneOf()) {
      String ref = schema.get$ref();
      if (ref == null) {
        throw new IllegalArgumentException("invalid oneOf schema");
      }
      String schemaName = refPointer.getRefName(ref);
      if (schemaName == null) {
        throw new IllegalArgumentException("invalid schema: " + ref);
      }
      reverseMapping.put(ref, schemaName);
    }

    if (composedSchema.getDiscriminator().getMapping() != null) {
      for (String ref : composedSchema.getDiscriminator().getMapping().keySet()) {
        reverseMapping.put(composedSchema.getDiscriminator().getMapping().get(ref), ref);
      }
    }

    return reverseMapping.entrySet().stream()
        .collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy