/** * Finds any bundle in the graph with the same ObjectIdentifier. If there is no bundle with this * identifier, it is created. If it exists and a Description in the given language exists from the * same source file, the description is replaced. If the description is from another source, it is * added to the bundle's descriptions. * * @param unit the DocumentaryUnit to be saved * @param descBundle the documentsDescription to replace any previous ones with this language * @param idPath the ID path of this bundle (will be relative to the ID path of the permission * scope) * @return A bundle with description relationships merged. */ protected Bundle mergeWithPreviousAndSave(Bundle unit, Bundle descBundle, List<String> idPath) throws ValidationError { final String languageOfDesc = descBundle.getDataValue(Ontology.LANGUAGE_OF_DESCRIPTION); final String thisSourceFileId = descBundle.getDataValue(Ontology.SOURCEFILE_KEY); logger.debug( "merging: descBundle's language = {}, sourceFileId = {}", languageOfDesc, thisSourceFileId); /* * for some reason, the idpath from the permissionscope does not contain the parent documentary unit. * TODO: so for now, it is added manually */ List<String> itemIdPath = Lists.newArrayList(getPermissionScope().idPath()); itemIdPath.addAll(idPath); Bundle unitWithIds = unit.generateIds(itemIdPath); logger.debug("merging: docUnit's graph id = {}", unitWithIds.getId()); // If the bundle exists, we merge if (manager.exists(unitWithIds.getId())) { try { // read the current item’s bundle Bundle oldBundle = mergeSerializer.vertexToBundle(manager.getVertex(unitWithIds.getId())); // filter out dependents that a) are descriptions, b) have the same language/code, // and c) have the same source file ID BiPredicate<String, Bundle> filter = (relationLabel, bundle) -> { String lang = bundle.getDataValue(Ontology.LANGUAGE); String oldSourceFileId = bundle.getDataValue(Ontology.SOURCEFILE_KEY); return relationLabel.equals(Ontology.DESCRIPTION_FOR_ENTITY) && bundle.getType().equals(EntityClass.DOCUMENTARY_UNIT_DESCRIPTION) && (lang != null && lang.equals(languageOfDesc)) && (oldSourceFileId != null && oldSourceFileId.equals(thisSourceFileId)); }; Bundle filtered = oldBundle.filterRelations(filter); return unitWithIds .withRelations(filtered.getRelations()) .withRelation(Ontology.DESCRIPTION_FOR_ENTITY, descBundle); } catch (SerializationError ex) { throw new ValidationError(unit, "serialization error", ex.getMessage()); } catch (ItemNotFound ex) { throw new ValidationError(unit, "item not found exception", ex.getMessage()); } } else { // else we create a new bundle. return unit.withRelation(Ontology.DESCRIPTION_FOR_ENTITY, descBundle); } }
/** * Import a single archdesc or c01-12 item, keeping a reference to the hierarchical depth. * * @param itemData The raw data map * @param idPath The identifiers of parent documents, not including those of the overall * permission scope * @throws ValidationError when the itemData does not contain an identifier for the unit or... */ @Override public AbstractUnit importItem(Map<String, Object> itemData, List<String> idPath) throws ValidationError { BundleManager persister = getPersister(idPath); Bundle description = getDescription(itemData); // extractDocumentaryUnit does not throw ValidationError on missing ID Bundle unit = new Bundle(unitEntity, extractDocumentaryUnit(itemData)); // Check for missing identifier, throw an exception when there is no ID. if (unit.getDataValue(Ontology.IDENTIFIER_KEY) == null) { throw new ValidationError( unit, Ontology.IDENTIFIER_KEY, "Missing identifier " + Ontology.IDENTIFIER_KEY); } logger.debug("Imported item: {}", itemData.get("name")); Mutation<DocumentaryUnit> mutation = persister.createOrUpdate( mergeWithPreviousAndSave(unit, description, idPath), DocumentaryUnit.class); DocumentaryUnit frame = mutation.getNode(); // Set the repository/item relationship if (idPath.isEmpty() && mutation.created()) { EntityClass scopeType = manager.getEntityClass(permissionScope); if (scopeType.equals(EntityClass.REPOSITORY)) { Repository repository = framedGraph.frame(permissionScope.asVertex(), Repository.class); frame.setRepository(repository); frame.setPermissionScope(repository); } else if (scopeType.equals(unitEntity)) { DocumentaryUnit parent = framedGraph.frame(permissionScope.asVertex(), DocumentaryUnit.class); parent.addChild(frame); frame.setPermissionScope(parent); } else { logger.error("Unknown scope type for documentary unit: {}", scopeType); } } handleCallbacks(mutation); logger.debug("============== {} state: {}", frame.getId(), mutation.getState()); if (mutation.created()) { solveUndeterminedRelationships(frame); } return frame; }