async def from_object( ctx: 'CdmCorpusContext', obj: 'Model', folder: 'CdmFolderDefinition' ) -> Optional['CdmManifestDefinition']: extension_trait_def_list = [] manifest = ctx.corpus.make_object(CdmObjectType.MANIFEST_DEF, obj.name) # we need to set up folder path and namespace of a folio to be able to retrieve that object. folder.documents.append(manifest, manifest.name) imports = obj.get('imports') if imports: for an_import in imports: import_obj = ImportPersistence.from_data(ctx, an_import) manifest.imports.append(import_obj) if not any( (import_present.corpus_path == Constants._FOUNDATIONS_CORPUS_PATH for import_present in manifest.imports)): manifest.imports.append(Constants._FOUNDATIONS_CORPUS_PATH) if obj.get('modifiedTime'): manifest.last_file_modified_time = dateutil.parser.parse( obj.get('modifiedTime')) if obj.get('lastChildFileModifiedTime'): manifest.last_child_file_modified_time = dateutil.parser.parse( obj.get('lastChildFileModifiedTime')) if obj.get('lastFileStatusCheckTime'): manifest.last_file_status_check_time = dateutil.parser.parse( obj.get('lastFileStatusCheckTime')) if not StringUtils.is_blank_by_cdm_standard( obj.get('documentVersion')): manifest.document_version = obj.get('documentVersion') if obj.get('application'): application_trait = ctx.corpus.make_object(CdmObjectType.TRAIT_REF, 'is.managedBy', False) arg = ctx.corpus.make_object(CdmObjectType.ARGUMENT_DEF, 'application') arg.value = obj.application application_trait.arguments.append(arg) manifest.exhibits_traits.append(application_trait) if obj.get('version'): version_trait = ctx.corpus.make_object( CdmObjectType.TRAIT_REF, 'is.modelConversion.modelVersion', False) arg = ctx.corpus.make_object(CdmObjectType.ARGUMENT_DEF, 'version') arg.value = obj.version version_trait.arguments.append(arg) manifest.exhibits_traits.append(version_trait) if obj.get('culture'): culture_trait = ctx.corpus.make_object(CdmObjectType.TRAIT_REF, 'is.partition.culture', False) arg = ctx.corpus.make_object(CdmObjectType.ARGUMENT_DEF, 'culture') arg.value = obj.culture culture_trait.arguments.append(arg) manifest.exhibits_traits.append(culture_trait) isHidden = obj.get('isHidden') if isHidden: is_hidden_trait = ctx.corpus.make_object(CdmObjectType.TRAIT_REF, 'is.hidden', True) is_hidden_trait.is_from_property = True manifest.exhibits_traits.append(is_hidden_trait) reference_models = {} if obj.get('referenceModels'): # Create a trait and put reference models inside an argument that goes inside the trait. reference_models_trait = ctx.corpus.make_object( CdmObjectType.TRAIT_REF, 'is.modelConversion.referenceModelMap', False) reference_model_arg = ctx.corpus.make_object( CdmObjectType.ARGUMENT_DEF, 'referenceModelMap') reference_model_arg.value = obj.referenceModels reference_models_trait.arguments.append(reference_model_arg) manifest.exhibits_traits.append(reference_models_trait) for element in obj.referenceModels: reference_models[element.id] = element.location entity_schema_by_name = {} for element in (obj.entities or []): entity = None if element.type == 'LocalEntity': entity = await LocalEntityDeclarationPersistence.from_data( ctx, folder, element, extension_trait_def_list, manifest) elif element.type == 'ReferenceEntity': reference_entity = element location = reference_models.get(reference_entity.modelId) if not location: logger.error( ctx, _TAG, "from_object", None, CdmLogCode.ERR_PERSIST_MODELJSON_MODEL_ID_NOT_FOUND, reference_entity.modelId, reference_entity.name) return None entity = await ReferencedEntityDeclarationPersistence.from_data( ctx, reference_entity, location) else: logger.error( ctx, _TAG, 'from_object', None, CdmLogCode.ERR_PERSIST_MODELJSON_ENTITY_PARSING_ERROR) if entity: manifest.entities.append(entity) entity_schema_by_name[entity.entity_name] = entity.entity_path else: logger.error( ctx, _TAG, 'from_object', None, CdmLogCode.ERR_PERSIST_MODELJSON_ENTITY_PARSING_ERROR) if obj.get('relationships'): for relationship in obj.get('relationships'): relationship = await RelationshipPersistence.from_data( ctx, relationship, entity_schema_by_name) if relationship: manifest.relationships.append(relationship) else: logger.warning( ctx, _TAG, ManifestPersistence.from_object.__name__, None, CdmLogCode.WARN_PERSIST_MODELJSON_REL_READ_FAILED) await utils.process_annotations_from_data(ctx, obj, manifest.exhibits_traits) local_extension_trait_def_list = [] # type: List['CdmTraitDefinition'] extension_helper.process_extension_from_json( ctx, obj, manifest.exhibits_traits, extension_trait_def_list, local_extension_trait_def_list) import_docs = await extension_helper.standard_import_detection( ctx, extension_trait_def_list, local_extension_trait_def_list) # type: List[CdmImport] extension_helper.add_import_docs_to_manifest(ctx, import_docs, manifest) ManifestPersistence.create_extension_doc_and_add_to_folder_and_imports( ctx, extension_trait_def_list, folder) return manifest
async def to_data(instance: 'CdmManifestDefinition', res_opt: 'ResolveOptions', options: 'CopyOptions') -> Optional['Model']: result = Model() # process_traits_and_annotations_to_data also processes extensions. utils.process_traits_and_annotations_to_data(instance.ctx, result, instance.exhibits_traits) result.name = instance.manifest_name result.description = instance.explanation result.modifiedTime = utils.get_formatted_date_string(instance.last_file_modified_time) result.lastChildFileModifiedTime = utils.get_formatted_date_string(instance.last_child_file_modified_time) result.lastFileStatusCheckTime = utils.get_formatted_date_string(instance.last_file_status_check_time) result.documentVersion = instance.document_version t2pm = TraitToPropertyMap(instance) result.isHidden = bool(t2pm._fetch_trait_reference('is.hidden')) or None application_trait = t2pm._fetch_trait_reference('is.managedBy') if application_trait: result.application = application_trait.arguments[0].value version_trait = t2pm._fetch_trait_reference('is.modelConversion.modelVersion') if version_trait: result.version = version_trait.arguments[0].value else: result.version = '1.0' culture_trait = t2pm._fetch_trait_reference('is.partition.culture') if culture_trait: result.culture = culture_trait.arguments[0].value reference_entity_locations = {} reference_models = OrderedDict() reference_models_trait = t2pm._fetch_trait_reference('is.modelConversion.referenceModelMap') if reference_models_trait: ref_models = reference_models_trait.arguments[0].value for element in ref_models: reference_models[element.id] = element.location reference_entity_locations[element.location] = element.id if instance.entities: result.entities = [] # Schedule processing of each entity to be added to the manifest for entity in instance.entities: element = None if entity.object_type == CdmObjectType.LOCAL_ENTITY_DECLARATION_DEF: element = await LocalEntityDeclarationPersistence.to_data(entity, instance, res_opt, options) elif entity.object_type == CdmObjectType.REFERENCED_ENTITY_DECLARATION_DEF: element = await ReferencedEntityDeclarationPersistence.to_data(entity, res_opt, options) location = instance.ctx.corpus.storage.corpus_path_to_adapter_path(entity.entity_path) if not location: logger.error(_TAG, instance.ctx, 'Invalid entity path set in entity {}'.format(entity.entity_name)) element = None reference_entity = element # type: ReferenceEntity if reference_entity: location = location[:location.rfind('/')] if reference_entity.modelId: saved_location = reference_models.get(reference_entity.modelId) if saved_location is not None and saved_location != location: logger.error(_TAG, instance.ctx, 'Same ModelId pointing to different locations') element = None elif saved_location is None: reference_models[reference_entity.modelId] = location reference_entity_locations[location] = reference_entity.modelId elif not reference_entity.modelId and location in reference_entity_locations: reference_entity.modelId = reference_entity_locations[location] else: reference_entity.modelId = str(uuid.uuid4()) reference_models[reference_entity.modelId] = location reference_entity_locations[location] = reference_entity.modelId if element: result.entities.append(element) else: logger.error(_TAG, instance.ctx, 'There was an error while trying to convert {}\'s entity declaration to model json format.'.format(entity.entity_name)) if reference_models: result.referenceModels = [] for value, key in reference_models.items(): model = ReferenceModel() model.id = value model.location = key result.referenceModels.append(model) if instance.relationships is not None and len(instance.relationships) > 0: result.relationships = [] # type: List[SingleKeyRelationship] for cdm_relationship in instance.relationships: relationship = await RelationshipPersistence.to_data(cdm_relationship, res_opt, options, instance.ctx) if relationship is not None: result.relationships.append(relationship) else: logger.error(_TAG, instance.ctx, 'There was an error while trying to convert cdm relationship to model.json relationship.') return None if instance.imports: result.imports = [] for element in instance.imports: import_obj = ImportPersistence.to_data(element, res_opt, options) if import_obj: result.imports.append(import_obj) return result
async def to_data(instance: 'CdmManifestDefinition', res_opt: 'ResolveOptions', options: 'CopyOptions') -> Optional['Model']: result = Model() # process_traits_and_annotations_to_data also processes extensions. await utils.process_traits_and_annotations_to_data( instance.ctx, result, instance.exhibits_traits) result.name = instance.manifest_name result.description = instance.explanation result.modifiedTime = utils.get_formatted_date_string( instance.last_file_modified_time) result.lastChildFileModifiedTime = utils.get_formatted_date_string( instance.last_child_file_modified_time) result.lastFileStatusCheckTime = utils.get_formatted_date_string( instance.last_file_status_check_time) result.documentVersion = instance.document_version t2pm = TraitToPropertyMap(instance) result.isHidden = bool( t2pm._fetch_trait_reference('is.hidden')) or None application_trait = t2pm._fetch_trait_reference('is.managedBy') if application_trait: result.application = application_trait.arguments[0].value version_trait = t2pm._fetch_trait_reference( 'is.modelConversion.modelVersion') if version_trait: result.version = version_trait.arguments[0].value else: result.version = '1.0' culture_trait = t2pm._fetch_trait_reference('is.partition.culture') if culture_trait: result.culture = culture_trait.arguments[0].value reference_entity_locations = {} reference_models = OrderedDict() reference_models_trait = t2pm._fetch_trait_reference( 'is.modelConversion.referenceModelMap') if reference_models_trait: ref_models = reference_models_trait.arguments[0].value for element in ref_models: reference_models[element.id] = element.location reference_entity_locations[element.location] = element.id if instance.entities: result.entities = [] # Schedule processing of each entity to be added to the manifest for entity in instance.entities: element = None if entity.object_type == CdmObjectType.LOCAL_ENTITY_DECLARATION_DEF: element = await LocalEntityDeclarationPersistence.to_data( entity, instance, res_opt, options) elif entity.object_type == CdmObjectType.REFERENCED_ENTITY_DECLARATION_DEF: element = await ReferencedEntityDeclarationPersistence.to_data( entity, res_opt, options) location = instance.ctx.corpus.storage.corpus_path_to_adapter_path( entity.entity_path) if StringUtils.is_blank_by_cdm_standard(location): logger.error( instance.ctx, _TAG, 'to_data', instance.at_corpus_path, CdmLogCode. ERR_PERSIST_MODELJSON_INVALID_ENTITY_PATH, entity.entity_name) element = None reference_entity = element # type: ReferenceEntity if reference_entity: # path separator can differ depending on the adapter, cover the case where path uses '/' or '\' last_slash_location = location.rfind( '/') if location.rfind('/') > location.rfind( '\\') else location.rfind('\\') if last_slash_location > 0: location = location[:last_slash_location] if reference_entity.modelId: saved_location = reference_models.get( reference_entity.modelId) if saved_location is not None and saved_location != location: logger.error( instance.ctx, 'to_data', instance.at_corpus_path, _TAG, CdmLogCode. ERR_PERSIST_MODELJSON_MODEL_ID_DUPLICATION) element = None elif saved_location is None: reference_models[ reference_entity.modelId] = location reference_entity_locations[ location] = reference_entity.modelId elif not reference_entity.modelId and location in reference_entity_locations: reference_entity.modelId = reference_entity_locations[ location] else: reference_entity.modelId = str(uuid.uuid4()) reference_models[ reference_entity.modelId] = location reference_entity_locations[ location] = reference_entity.modelId if element: result.entities.append(element) else: logger.error( instance.ctx, _TAG, 'to_data', instance.at_corpus_path, CdmLogCode. ERR_PERSIST_MODELJSON_ENTITY_DECLARATION_CONVERSION_ERROR, entity.entity_name) if reference_models: result.referenceModels = [] for value, key in reference_models.items(): model = ReferenceModel() model.id = value model.location = key result.referenceModels.append(model) if instance.relationships is not None and len( instance.relationships) > 0: result.relationships = [] # type: List[SingleKeyRelationship] for cdm_relationship in instance.relationships: relationship = await RelationshipPersistence.to_data( cdm_relationship, res_opt, options, instance.ctx) if relationship is not None: result.relationships.append(relationship) result.imports = [] if instance.imports: for element in instance.imports: import_obj = ImportPersistence.to_data(element, res_opt, options) if import_obj: result.imports.append(import_obj) # Importing foundations.cdm.json to resolve trait properly on manifest if instance.imports is None or instance.imports.item( Constants._FOUNDATIONS_CORPUS_PATH, check_moniker=False) is None: foundations_import = Import() foundations_import.corpusPath = Constants._FOUNDATIONS_CORPUS_PATH result.imports.append(foundations_import) return result
async def from_data( ctx: 'CdmCorpusContext', obj: 'Model', folder: 'CdmFolderDefinition' ) -> Optional['CdmManifestDefinition']: extension_trait_def_list = [] extension_doc = ctx.corpus.make_object( CdmObjectType.DOCUMENT_DEF, '{}.extension.cdm.json'.format(folder.name or folder.namespace)) manifest = ctx.corpus.make_object(CdmObjectType.MANIFEST_DEF, obj.name) # We need to set up folder path and namespace of a manifest to be able to retrieve that object. manifest.folder_path = folder.folder_path manifest.namespace = folder.namespace manifest.explanation = obj.description if obj.get('modifiedTime'): manifest.last_file_modified_time = dateutil.parser.parse( obj.get('modifiedTime')) if obj.get('lastChildFileModifiedTime'): manifest.last_child_file_modified_time = dateutil.parser.parse( obj.get('lastChildFileModifiedTime')) if obj.get('lastFileStatusCheckTime'): manifest.last_file_status_check_time = dateutil.parser.parse( obj.get('lastFileStatusCheckTime')) if obj.get('application'): application_trait = ctx.corpus.make_object(CdmObjectType.TRAIT_REF, 'is.managedBy', False) arg = ctx.corpus.make_object(CdmObjectType.ARGUMENT_DEF, 'application') arg.value = obj.application application_trait.arguments.append(arg) manifest.exhibits_traits.append(application_trait) if obj.get('version'): version_trait = ctx.corpus.make_object( CdmObjectType.TRAIT_REF, 'means.measurement.version', False) arg = ctx.corpus.make_object(CdmObjectType.ARGUMENT_DEF, 'version') arg.value = obj.version version_trait.arguments.append(arg) manifest.exhibits_traits.append(version_trait) if obj.get('culture'): culture_trait = ctx.corpus.make_object(CdmObjectType.TRAIT_REF, 'is.partition.culture', False) arg = ctx.corpus.make_object(CdmObjectType.ARGUMENT_DEF, 'culture') arg.value = obj.culture culture_trait.arguments.append(arg) manifest.exhibits_traits.append(culture_trait) isHidden = obj.get('isHidden') if isHidden: is_hidden_trait = ctx.corpus.make_object(CdmObjectType.TRAIT_REF, 'is.hidden', True) is_hidden_trait.is_from_property = True manifest.exhibits_traits.append(is_hidden_trait) reference_models = {} if obj.get('referenceModels'): # Create a trait and put reference models inside an argument that goes inside the trait. reference_models_trait = ctx.corpus.make_object( CdmObjectType.TRAIT_REF, 'is.modelConversion.referenceModelMap', False) reference_model_arg = ctx.corpus.make_object( CdmObjectType.ARGUMENT_DEF, 'referenceModelMap') reference_model_arg.value = obj.referenceModels reference_models_trait.arguments.append(reference_model_arg) manifest.exhibits_traits.append(reference_models_trait) for element in obj.referenceModels: reference_models[element.id] = element.location entity_schema_by_name = {} for element in (obj.entities or []): entity = None if element.type == 'LocalEntity': entity = await LocalEntityDeclarationPersistence.from_data( ctx, folder, element, extension_trait_def_list) elif element.type == 'ReferenceEntity': reference_entity = element location = reference_models.get(reference_entity.modelId) if not location: ctx.logger.error( 'Model Id %s from %s not found in reference_models.', reference_entity.modelId, reference_entity.name) return entity = await ReferencedEntityDeclarationPersistence.from_data( ctx, reference_entity, location, extension_trait_def_list) else: ctx.logger.error( 'There was an error while trying to parse entity type.') return if entity: # make path relative for entities created here entity.entity_path = ctx.corpus.storage.create_relative_corpus_path( entity.entity_path, manifest) manifest.entities.append(entity) entity_schema_by_name[entity.entity_name] = entity.entity_path else: ctx.logger.error( 'There was an error while trying to parse entity type.') return if obj.get('relationships'): for relationship in obj.get('relationships'): relationship = await RelationshipPersistence.from_data( ctx, relationship, entity_schema_by_name) if relationship: manifest.relationships.append(relationship) else: ctx.logger.error( 'There was an error while trying to convert model.json local entity to cdm local entity declaration.' ) return None imports = obj.get('imports') if imports: for an_import in imports: import_obj = ImportPersistence.from_data(ctx, an_import) manifest.imports.append(import_obj) await utils.process_annotations_from_data(ctx, obj, manifest.exhibits_traits) await extension_helper.process_extension_from_json( ctx, obj, manifest.exhibits_traits, extension_trait_def_list) import_docs = await extension_helper.standard_import_detection( ctx, extension_trait_def_list) # type: List[CdmImport] ManifestPersistence.create_extension_doc_and_add_to_folder_and_imports( ctx, extension_doc, extension_trait_def_list, folder, import_docs) await ManifestPersistence.add_import_docs_to_manifest( ctx, import_docs, manifest) return manifest