示例#1
0
  /**
   * 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");
        }
      }
    }
  }
 @Override
 @Before
 public void setUp() throws Exception {
   super.setUp();
   instance = IdentifiableEntityIdGenerator.INSTANCE;
   scopes = Lists.newArrayList("r1");
   bundle = Bundle.fromData(TestData.getTestDocBundle());
 }
示例#3
0
  /**
   * 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;
  }
示例#4
0
  /**
   * 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);
    }
  }