public CompletableFuture createResolvedManifestAsync()

in objectModel/Java/objectmodel/src/main/java/com/microsoft/commondatamodel/objectmodel/cdm/CdmManifestDefinition.java [526:696]


  public CompletableFuture<CdmManifestDefinition> createResolvedManifestAsync(
      final String newManifestName,
      final String newEntityDocumentNameFormat,
      final AttributeResolutionDirectiveSet directives) {
    return CompletableFuture.supplyAsync(() -> {
      try (Logger.LoggerScope logScope = Logger.enterScope(CdmManifestDefinition.class.getSimpleName(), getCtx(), "createResolvedManifestAsync")) {

        String innerNewEntityDocumentNameFormat = newEntityDocumentNameFormat;
        String innerNewManifestName = newManifestName;

        if (null == this.getEntities()) {
          return null;
        }

        if (this.getFolder() == null) {
          Logger.error(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), CdmLogCode.ErrResolveManifestFailed, this.manifestName);
          return null;
        }

        if (null == innerNewEntityDocumentNameFormat) {
          innerNewEntityDocumentNameFormat = "{f}resolved/{n}.cdm.json";
        } else if (innerNewEntityDocumentNameFormat.isEmpty()) { // For backwards compatibility.
          innerNewEntityDocumentNameFormat = "{n}.cdm.json";
        } else if (!innerNewEntityDocumentNameFormat.contains("{n}")) { // For backwards compatibility.
          innerNewEntityDocumentNameFormat = innerNewEntityDocumentNameFormat + "/{n}.cdm.json";
        }

        final String sourceManifestPath = this.getCtx().getCorpus()
                .getStorage()
                .createAbsoluteCorpusPath(this.getAtCorpusPath(), this);
        final String sourceManifestFolderPath = this.getCtx().getCorpus()
                .getStorage()
                .createAbsoluteCorpusPath(this.getFolder().getAtCorpusPath(), this);

        int resolvedManifestPathSplit = innerNewManifestName.lastIndexOf("/") + 1;
        CdmFolderDefinition resolvedManifestFolder;
        if (resolvedManifestPathSplit > 0) {
          String resolvedManifestPath = innerNewManifestName.substring(0, resolvedManifestPathSplit);
          final String newFolderPath = this.getCtx().getCorpus()
                  .getStorage()
                  .createAbsoluteCorpusPath(resolvedManifestPath, this);
          resolvedManifestFolder = this.getCtx()
                  .getCorpus()
                  .<CdmFolderDefinition>fetchObjectAsync(newFolderPath).join();
          if (resolvedManifestFolder == null) {
            Logger.error( this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), CdmLogCode.ErrResolveFolderNotFound, newFolderPath);
            return null;
          }
          innerNewManifestName = innerNewManifestName.substring(resolvedManifestPathSplit);
        } else {
          resolvedManifestFolder = (CdmFolderDefinition) this.getOwner();
        }

        if (resolvedManifestFolder.getDocuments().item(newManifestName) != null) {
          Logger.error(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), CdmLogCode.ErrResolveManifestExists, newManifestName, resolvedManifestFolder.getAtCorpusPath());
          return null;
        }

        Logger.debug(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), Logger.format("Resolving manifest '{0}'", sourceManifestPath));

        // Using the references present in the resolved entities, get an entity.
        // Create an imports doc with all the necessary resolved entity references and then resolve it.
        // sometimes they might send the docname, that makes sense a bit, don't include the suffix in the name
        if (innerNewManifestName.toLowerCase().endsWith(".manifest.cdm.json")) {
          innerNewManifestName = innerNewManifestName.substring(0, innerNewManifestName.length() - ".manifest.cdm.json".length());
        }
        final CdmManifestDefinition resolvedManifest = new CdmManifestDefinition(this.getCtx(), innerNewManifestName);

        // bring over any imports in this document or other bobbles
        resolvedManifest.setSchema(this.getSchema());
        resolvedManifest.setExplanation(this.getExplanation());
        resolvedManifest.setDocumentVersion(this.getDocumentVersion());
        for (CdmImport imp : this.getImports()) {
          resolvedManifest.getImports().add((CdmImport) imp.copy());
        }

        // Add the new document to the folder.
        if (resolvedManifestFolder.getDocuments().add(resolvedManifest) == null) {
          // When would this happen?
          return null;
        }

        for (final CdmEntityDeclarationDefinition entity : this.getEntities()) {
          final String entityPath = this.createEntityPathFromDeclarationAsync(entity, this).join();
          final CdmEntityDefinition entDef = this.getCtx()
                                              .getCorpus()
                                              .<CdmEntityDefinition>fetchObjectAsync(entityPath)
                                              .join();
          if (null == entDef) {
            Logger.error(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), CdmLogCode.ErrResolveEntityFailure, entityPath);
            return null;
          }

          if (entDef.getInDocument().getFolder() == null) {
            Logger.error(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), CdmLogCode.ErrDocIsNotFolder, entDef.getEntityName());
            return null;
          }

          // get the path from this manifest to the source entity. this will be the {f} replacement value
          String sourceEntityFullPath = this.getCtx()
                  .getCorpus()
                  .getStorage()
                  .createAbsoluteCorpusPath(entDef.getInDocument().getFolder().getAtCorpusPath(), this);
          String f = "";
          if (sourceEntityFullPath.startsWith(sourceManifestFolderPath)) {
            f = sourceEntityFullPath.substring(sourceManifestFolderPath.length());
          }

          // Make sure the new folder exists.
          String newDocumentFullPath = innerNewEntityDocumentNameFormat
                  .replace("{n}", entDef.getEntityName());
          newDocumentFullPath = newDocumentFullPath.replace("{f}", f);
          newDocumentFullPath = this.getCtx()
                  .getCorpus()
                  .getStorage()
                  .createAbsoluteCorpusPath(newDocumentFullPath, this);
          final int newDocumentPathSplit = newDocumentFullPath.lastIndexOf("/") + 1;
          final String newDocumentPath = newDocumentFullPath.substring(0, newDocumentPathSplit);
          final String newDocumentName = newDocumentFullPath.substring(newDocumentPathSplit);

          final CdmFolderDefinition folder =
                  this.getCtx().getCorpus().<CdmFolderDefinition>fetchObjectAsync(newDocumentPath).join();
          if (null == folder) {
            Logger.error(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), CdmLogCode.ErrResolveFolderNotFound, newDocumentPath);
            return null;
          }

          // Next create the resolved entity.
          AttributeResolutionDirectiveSet withDirectives =
                  directives != null ? directives : this.getCtx().getCorpus().getDefaultResolutionDirectives();
          final ResolveOptions resOpt = new ResolveOptions(entDef.getInDocument(), withDirectives != null ? withDirectives.copy() : null);
          Logger.debug(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), Logger.format("resolving entity {0} to document {1}", sourceEntityFullPath, newDocumentFullPath));

          final CdmEntityDefinition resolvedEntity = entDef
                  .createResolvedEntityAsync(entDef.getEntityName(), resOpt, folder, newDocumentName).join();

          if (null == resolvedEntity) {
            // Fail all resolution, if any one entity resolution fails.
            return null;
          }

          CdmEntityDeclarationDefinition result = (CdmEntityDeclarationDefinition) entity.copy(resOpt);
          if (result.getObjectType() == CdmObjectType.LocalEntityDeclarationDef) {
            result.setEntityPath(
                    ObjectUtils.firstNonNull(
                            this.getCtx()
                                    .getCorpus()
                                    .getStorage()
                                    .createRelativeCorpusPath(resolvedEntity.getAtCorpusPath(), resolvedManifest),
                            result.getAtCorpusPath()));
          }

          resolvedManifest.getEntities().add(result);
        }

        Logger.debug(this.getCtx(), TAG, "createResolvedManifestAsync", this.getAtCorpusPath(), "calculating relationships");

        // Calculate the entity graph for just this folio and any subManifests.
        this.getCtx().getCorpus().calculateEntityGraphAsync(resolvedManifest).join();
        // Stick results into the relationships list for the manifest.
        // Only put in relationships that are between the entities that are used in the manifest.
        resolvedManifest.populateManifestRelationshipsAsync(
                CdmRelationshipDiscoveryStyle.Exclusive
        ).join();

        // Needed until Matt's changes with collections where I can propagate.
        resolvedManifest.setDirty(true);
        return resolvedManifest;
      }
    });
  }