/** * Subclasses can override this method to cater to their special needs for * UndeterminedRelationships by default, it expects something like this in the original EAD: * * <p> * * <pre>{@code * <persname source="terezin-victims" authfilenumber="PERSON.ITI.1514982">Kien, * Leonhard (* 11.5.1886)</persname> * }</pre> * * <p>it works in unison with the extractRelations() method. * * @param unit the current unit */ protected void solveUndeterminedRelationships(DocumentaryUnit unit) throws ValidationError { // Try to resolve the undetermined relationships // we can only create the annotations after the DocumentaryUnit // and its Description have been added to the graph, // so they have IDs. Api api = ApiFactory.noLogging(framedGraph, actioner.as(UserProfile.class)); Bundle linkBundle = new Bundle(EntityClass.LINK) .withDataValue(Ontology.LINK_HAS_DESCRIPTION, RESOLVED_LINK_DESC); for (Description desc : unit.getDescriptions()) { // Put the set of relationships into a HashSet to remove duplicates. for (AccessPoint rel : Sets.newHashSet(desc.getAccessPoints())) { // the wp2 undetermined relationship that can be resolved have a 'cvoc' and a 'concept' // attribute. // they need to be found in the vocabularies that are in the graph if (rel.getPropertyKeys().contains("cvoc")) { String vocab = rel.getProperty("cvoc"); String conceptId = rel.getProperty("concept"); if (conceptId == null) { conceptId = rel.getProperty("target"); } logger.debug("cvoc: {}, concept: {}", vocab, conceptId); try { Vocabulary vocabulary = manager.getEntity(vocab, Vocabulary.class); for (Concept concept : vocabulary.getConcepts()) { logger.debug("********************* {} {}", concept.getId(), concept.getIdentifier()); if (concept.getIdentifier().equalsIgnoreCase(conceptId)) { try { // TODO: Fix link type here... Bundle data = linkBundle.withDataValue(Ontology.LINK_HAS_TYPE, "associative"); Link link = api.create(data, Link.class); unit.addLink(link); concept.addLink(link); link.addLinkBody(rel); logger.debug("link created between {} and {}", conceptId, concept.getId()); } catch (PermissionDenied | DeserializationError ex) { logger.error(ex.getMessage()); } } } } catch (ItemNotFound ex) { logger.error("Vocabulary with id {} not found: {}", vocab, ex.getMessage()); } } else { logger.debug("no cvoc found"); } } } }
// Sort the children by identifier. FIXME: This might be a bad assumption! private Iterable<DocumentaryUnit> getOrderedChildren(DocumentaryUnit unit) { return api.query() .orderBy(Ontology.IDENTIFIER_KEY, QueryApi.Sort.ASC) .setLimit(-1) .setStream(true) .page(unit.getChildren(), DocumentaryUnit.class); }
private void addRevisionDesc(XMLStreamWriter sw, DocumentaryUnit unit) { List<List<SystemEvent>> eventList = Lists.newArrayList(api.events().aggregateForItem(unit)); if (!eventList.isEmpty()) { tag( sw, "revisiondesc", () -> { for (int i = eventList.size() - 1; i >= 0; i--) { List<SystemEvent> agg = eventList.get(i); SystemEvent event = agg.get(0); tag( sw, "change", () -> { tag(sw, "date", new DateTime(event.getTimestamp()).toString()); if (event.getLogMessage() == null || event.getLogMessage().isEmpty()) { tag(sw, "item", event.getEventType().name()); } else { tag( sw, "item", String.format("%s [%s]", event.getLogMessage(), event.getEventType())); } }); } }); } }