use of edu.stanford.bmir.protege.web.server.events.EventTranslatorManager in project webprotege by protegeproject.
the class ChangeManager method applyChanges.
/**
* Applies ontology changes to the ontologies contained within a project.
*
* @param userId The userId of the user applying the changes. Not {@code null}.
* @param changeListGenerator A generator which creates a list of changes (based on the state of the project at
* the time of change application). The idea behind passing in a change generator is that the list of changes to
* be applied can be created based on the state of the project immediately before they are applied. This is
* necessary where the changes depend on the structure/state of the ontology. This method guarantees that no third
* party
* ontology changes will take place between the {@link ChangeListGenerator#generateChanges(ChangeGenerationContext)}
* method being called and the changes being applied.
* @return A {@link ChangeApplicationResult} that describes the changes which took place an any renaminings.
* @throws NullPointerException if any parameters are {@code null}.
* @throws PermissionDeniedException if the user identified by {@code userId} does not have permssion to write to
* ontologies in this project.
*/
@Override
public <R> ChangeApplicationResult<R> applyChanges(final UserId userId, final ChangeListGenerator<R> changeListGenerator) throws PermissionDeniedException {
// noinspection ResultOfMethodCallIgnored
checkNotNull(userId);
// noinspection ResultOfMethodCallIgnored
checkNotNull(changeListGenerator);
// Final check of whether the user can actually edit the project
Subject subject = forUser(userId);
ProjectResource projectResource = new ProjectResource(projectId);
if (!accessManager.hasPermission(subject, projectResource, EDIT_ONTOLOGY.getActionId())) {
throw new PermissionDeniedException("You do not have permission to edit this project", userInSessionFactory.getUserInSession(userId));
}
final List<OWLOntologyChange> appliedChanges;
final ChangeApplicationResult<R> finalResult;
// with true entity IRIs
try {
// Compute the changes that need to take place. We don't allow any other writes here because the
// generation of the changes may depend upon the state of the project
changeProcesssingLock.lock();
final ChangeGenerationContext context = new ChangeGenerationContext(userId);
OntologyChangeList<R> gen = changeListGenerator.generateChanges(context);
// We have our changes
List<OWLOntologyChange> changes = gen.getChanges();
// We coin fresh entities for places where tmp: is the scheme - the name for the entity comes from
// the fragment
final Map<IRI, IRI> iriRenameMap = new HashMap<>();
final ChangeSetEntityCrudSession session = getEntityCrudKitHandler().createChangeSetSession();
Set<OWLOntologyChange> changesToRename = new HashSet<>();
List<OWLOntologyChange> freshEntityChanges = new ArrayList<>();
for (OWLOntologyChange change : changes) {
for (OWLEntity entity : change.getSignature()) {
if (DataFactory.isFreshEntity(entity)) {
if (entity.isOWLClass()) {
if (!accessManager.hasPermission(subject, projectResource, CREATE_CLASS.getActionId())) {
throw new PermissionDeniedException("You do not have permission to create new classes", userInSessionFactory.getUserInSession(userId));
}
} else if (entity.isOWLObjectProperty() || entity.isOWLDataProperty() || entity.isOWLAnnotationProperty()) {
if (!accessManager.hasPermission(subject, projectResource, CREATE_PROPERTY.getActionId())) {
throw new PermissionDeniedException("You do not have permission to create new properties", userInSessionFactory.getUserInSession(userId));
}
} else if (entity.isOWLNamedIndividual()) {
if (!accessManager.hasPermission(subject, projectResource, CREATE_INDIVIDUAL.getActionId())) {
throw new PermissionDeniedException("You do not have permission to create new individuals", userInSessionFactory.getUserInSession(userId));
}
} else if (entity.isOWLDatatype()) {
if (!accessManager.hasPermission(subject, projectResource, CREATE_DATATYPE.getActionId())) {
throw new PermissionDeniedException("You do not have permission to create new datatypes", userInSessionFactory.getUserInSession(userId));
}
}
changesToRename.add(change);
IRI currentIRI = entity.getIRI();
if (!iriRenameMap.containsKey(currentIRI)) {
String shortName = DataFactory.getFreshEntityShortName(entity);
OWLEntityCreator<? extends OWLEntity> creator = getEntityCreator(session, userId, shortName, (EntityType<? extends OWLEntity>) entity.getEntityType());
freshEntityChanges.addAll(creator.getChanges());
IRI replacementIRI = creator.getEntity().getIRI();
iriRenameMap.put(currentIRI, replacementIRI);
}
}
}
}
List<OWLOntologyChange> allChangesIncludingRenames = new ArrayList<>();
final OWLObjectDuplicator duplicator = new OWLObjectDuplicator(dataFactory, iriRenameMap);
for (OWLOntologyChange change : changes) {
if (changesToRename.contains(change)) {
OWLOntologyChange replacementChange = getRenamedChange(change, duplicator);
allChangesIncludingRenames.add(replacementChange);
} else {
allChangesIncludingRenames.add(change);
}
}
allChangesIncludingRenames.addAll(freshEntityChanges);
List<OWLOntologyChange> minimisedChanges = getMinimisedChanges(allChangesIncludingRenames);
final EventTranslatorManager eventTranslatorManager = eventTranslatorManagerProvider.get();
eventTranslatorManager.prepareForOntologyChanges(minimisedChanges);
// Now we do the actual changing, so we lock the project here. No writes or reads can take place whilst
// we apply the changes
final Optional<Revision> revision;
try {
projectChangeWriteLock.lock();
ProjectOWLOntologyManager manager = ((ProjectOWLOntologyManager) rootOntology.getOWLOntologyManager());
List<OWLOntologyChange> effectiveChanges = getEffectiveChanges(minimisedChanges);
manager.getDelegate().applyChanges(effectiveChanges);
appliedChanges = effectiveChanges;
final RenameMap renameMap = new RenameMap(iriRenameMap);
R renamedResult = getRenamedResult(changeListGenerator, gen.getResult(), renameMap);
finalResult = new ChangeApplicationResult<>(renamedResult, appliedChanges, renameMap);
if (!appliedChanges.isEmpty()) {
Revision rev = logAndBroadcastAppliedChanges(userId, changeListGenerator, finalResult);
revision = Optional.of(rev);
projectDetailsRepository.setModified(projectId, rev.getTimestamp(), userId);
} else {
revision = Optional.empty();
}
} finally {
// Release for reads
projectChangeWriteLock.unlock();
}
if (revision.isPresent() && !(changeListGenerator instanceof SilentChangeListGenerator)) {
List<ProjectEvent<?>> highLevelEvents = new ArrayList<>();
Revision rev = revision.get();
eventTranslatorManager.translateOntologyChanges(rev, finalResult, highLevelEvents);
if (changeListGenerator instanceof HasHighLevelEvents) {
highLevelEvents.addAll(((HasHighLevelEvents) changeListGenerator).getHighLevelEvents());
}
projectEventManager.postEvents(highLevelEvents);
projectChangedWebhookInvoker.invoke(userId, rev.getRevisionNumber(), rev.getTimestamp());
}
} finally {
changeProcesssingLock.unlock();
}
return finalResult;
}
Aggregations