All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.stanford.protege.webprotege.frame.FrameChangeGenerator Maven / Gradle / Ivy

The newest version!
package edu.stanford.protege.webprotege.frame;

import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import edu.stanford.protege.webprotege.change.*;
import edu.stanford.protege.webprotege.common.ChangeRequestId;
import edu.stanford.protege.webprotege.frame.translator.*;
import edu.stanford.protege.webprotege.index.OntologyAxiomsIndex;
import edu.stanford.protege.webprotege.index.ProjectOntologiesIndex;
import edu.stanford.protege.webprotege.owlapi.RenameMap;
import edu.stanford.protege.webprotege.project.DefaultOntologyIdManager;
import edu.stanford.protege.webprotege.renderer.RenderingManager;
import org.semanticweb.owlapi.model.*;

import javax.annotation.Nonnull;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static edu.stanford.protege.webprotege.change.RemoveAxiomChange.of;
import static java.util.stream.Collectors.toList;

/**
 * Author: Matthew Horridge
Stanford University
Bio-Medical Informatics Research Group
Date: 14/01/2013 */ public final class FrameChangeGenerator implements ChangeListGenerator { @Nonnull private final ChangeRequestId changeRequestId; @Nonnull private final FrameUpdate frameUpdate; @Nonnull private final ProjectOntologiesIndex projectOntologiesIndex; @Nonnull private final ReverseEngineeredChangeDescriptionGeneratorFactory factory; @Nonnull private final DefaultOntologyIdManager defaultOntologyIdManager; @Nonnull private final OntologyAxiomsIndex axiomsIndex; @Nonnull private final ObjectPropertyFrameTranslator objectPropertyFrameTranslator; @Nonnull private final DataPropertyFrameTranslator dataPropertyFrameTranslator; @Nonnull private final AnnotationPropertyFrameTranslator annotationPropertyFrameTranslator; @Nonnull private final NamedIndividualFrameTranslator namedIndividualFrameTranslator; @Nonnull private final RenderingManager renderingManager; @Nonnull private final ClassFrameProvider classFrameProvider; @Nonnull private final ClassFrame2FrameAxiomsTranslator classFrame2FrameAxiomsTranslator; @Inject public FrameChangeGenerator(@Nonnull ChangeRequestId changeRequestId, @Nonnull FrameUpdate frameUpdate, @Nonnull ProjectOntologiesIndex projectOntologiesIndex, @Nonnull ReverseEngineeredChangeDescriptionGeneratorFactory factory, @Nonnull DefaultOntologyIdManager defaultOntologyIdManager, @Nonnull OntologyAxiomsIndex axiomsIndex, @Nonnull ObjectPropertyFrameTranslator objectPropertyFrameTranslator, @Nonnull DataPropertyFrameTranslator dataPropertyFrameTranslator, @Nonnull AnnotationPropertyFrameTranslator annotationPropertyFrameTranslator, @Nonnull NamedIndividualFrameTranslator namedIndividualFrameTranslator, @Nonnull RenderingManager renderingManager, @Nonnull ClassFrameProvider classFrameProvider, @Nonnull ClassFrame2FrameAxiomsTranslator classFrame2FrameAxiomsTranslator) { this.changeRequestId = changeRequestId; this.frameUpdate = checkNotNull(frameUpdate); this.projectOntologiesIndex = checkNotNull(projectOntologiesIndex); this.factory = checkNotNull(factory); this.defaultOntologyIdManager = checkNotNull(defaultOntologyIdManager); this.axiomsIndex = checkNotNull(axiomsIndex); this.classFrameProvider = classFrameProvider; this.objectPropertyFrameTranslator = objectPropertyFrameTranslator; this.dataPropertyFrameTranslator = dataPropertyFrameTranslator; this.annotationPropertyFrameTranslator = annotationPropertyFrameTranslator; this.namedIndividualFrameTranslator = namedIndividualFrameTranslator; this.renderingManager = renderingManager; this.classFrame2FrameAxiomsTranslator = classFrame2FrameAxiomsTranslator; } @Override public ChangeRequestId getChangeRequestId() { return changeRequestId; } @Override public OntologyChangeList generateChanges(ChangeGenerationContext context) { var builder = new OntologyChangeList.Builder(); builder.addAll(createChanges()); return builder.build(frameUpdate.getToFrame().getSubject()); } private Set getAxiomsForFrame(Frame frame, Mode mode) { if(frame instanceof PlainClassFrame) { var classFrame = (PlainClassFrame) frame; return classFrame2FrameAxiomsTranslator.getAxioms(classFrame, mode); } else if(frame instanceof PlainObjectPropertyFrame) { var objectPropertyFrame = (PlainObjectPropertyFrame) frame; return objectPropertyFrameTranslator.getAxioms(objectPropertyFrame, mode); } else if(frame instanceof PlainDataPropertyFrame) { var dataPropertyFrame = (PlainDataPropertyFrame) frame; return dataPropertyFrameTranslator.getAxioms(dataPropertyFrame, mode); } else if(frame instanceof PlainAnnotationPropertyFrame) { var annotationPropertyFrame = (PlainAnnotationPropertyFrame) frame; return annotationPropertyFrameTranslator.getAxioms(annotationPropertyFrame, mode); } else if(frame instanceof PlainNamedIndividualFrame) { var namedIndividualFrame = (PlainNamedIndividualFrame) frame; return namedIndividualFrameTranslator.getAxioms(namedIndividualFrame, mode); } else { throw new RuntimeException("Cannot determine translator type"); } } private Frame getFrameForSubject(OWLEntity subject) { if(subject instanceof OWLClass) { return classFrameProvider.getFrame((OWLClass) subject, ClassFrameTranslationOptions.defaultOptions()); } else if(subject instanceof OWLObjectProperty) { return objectPropertyFrameTranslator.getFrame((OWLObjectProperty) subject); } else if(subject instanceof OWLDataProperty) { return dataPropertyFrameTranslator.getFrame((OWLDataProperty) subject); } else if(subject instanceof OWLAnnotationProperty) { return annotationPropertyFrameTranslator.getFrame((OWLAnnotationProperty) subject); } else if(subject instanceof OWLNamedIndividual) { return namedIndividualFrameTranslator.getFrame((OWLNamedIndividual) subject); } else { throw new RuntimeException("Cannot determine translator type"); } } public List createChanges() { // TODO: Consider axiom annotations! // TODO: Three way merge incase the frame has been modified "externally" and is different from the original // TODO: from frame // This looks like it is more complicated than necessary, however we need to consider the fact that // a frame may be generated from multiple axiomsSource (note the minimal and maximal translation) var to = frameUpdate.getToFrame(); var toSubject = to.getSubject(); Frame serverFrame = getFrameForSubject(toSubject); if(serverFrame.equals(to)) { // Nothing to do return Collections.emptyList(); } // Get the axiomsSource that were consumed in the translation var fromAxioms = getAxiomsForFrame(frameUpdate.getFromFrame(), Mode.MAXIMAL); var ontologyIds = projectOntologiesIndex.getOntologyIds() .collect(toList()); var toAxioms = getAxiomsForFrame(frameUpdate.getToFrame(), Mode.MINIMAL); var axiom2OntologyMap = LinkedHashMultimap.create(); // Generate a map of existing axiomsSource so we can ensure they stay in the correct place for(OWLOntologyID ontologyId : ontologyIds) { for(OWLAxiom fromAxiom : fromAxioms) { if(isContainedInOntology(fromAxiom, ontologyId)) { axiom2OntologyMap.put(fromAxiom, ontologyId); } } } var mutatedOntologies = Sets.newLinkedHashSet(); List changes = Lists.newArrayList(); for(OWLAxiom fromAxiom : fromAxioms) { for(OWLOntologyID ontologyId : ontologyIds) { if(isContainedInOntology(fromAxiom, ontologyId) && !toAxioms.contains(fromAxiom)) { mutatedOntologies.add(ontologyId); } // We need to add this here in case an axiom containing fresh entities has been added and then // removed (caused by a re-edit). The fresh entities will get "grounded" and then the axiom added // hence, ontology.contains() won't work. changes.add(of(ontologyId, fromAxiom)); } } for(OWLAxiom toAxiom : toAxioms) { Collection existingLocations = axiom2OntologyMap.get(toAxiom); if(existingLocations.isEmpty()) { // Fresh axiom to be placed somewhere if(mutatedOntologies.size() == 1) { // Assume edit i.e. replacement of axiom in the same ontology. changes.add(AddAxiomChange.of(mutatedOntologies.iterator() .next(), toAxiom)); } else { // Multiple ontologies were affected. We now need to place the fresh axiom in the appropriate // ontology OWLOntologyID freshAxiomOntology = getFreshAxiomOntology(fromAxioms, ontologyIds); changes.add(AddAxiomChange.of(freshAxiomOntology, toAxiom)); } } else { // Ensure it is still in there for(OWLOntologyID ontId : existingLocations) { changes.add(AddAxiomChange.of(ontId, toAxiom)); } } } return changes; } private boolean isContainedInOntology(OWLAxiom axiom, OWLOntologyID ontologyId) { return axiomsIndex.containsAxiomIgnoreAnnotations(axiom, ontologyId); } private OWLOntologyID getFreshAxiomOntology(Set fromAxioms, List importsClosure) { for(OWLOntologyID ontId : importsClosure) { for(OWLAxiom existingFrameAxiom : fromAxioms) { if(isContainedInOntology(existingFrameAxiom, ontId)) { return ontId; } } } return defaultOntologyIdManager.getDefaultOntologyId(); } @Override public OWLEntity getRenamedResult(OWLEntity result, RenameMap renameMap) { return renameMap.getRenamedEntity(result); } @Nonnull @Override public String getMessage(ChangeApplicationResult result) { var rendering = renderingManager.getRendering(frameUpdate.getFromFrame().getSubject()); return factory.get("Edited " + rendering.getBrowserText()) .generateChangeDescription(result); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy