/*
* Licensed under the Apache License, Version 2.0 (the "License");
*
* You may not use this file except in compliance with the License.
*
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributions from 2013-2017 where performed either by US government
* employees, or under US Veterans Health Administration contracts.
*
* US Veterans Health Administration contributions by government employees
* are work of the U.S. Government and are not subject to copyright
* protection in the United States. Portions contributed by government
* employees are USGovWork (17USC ยง105). Not subject to copyright.
*
* Contribution by contractors to the US Veterans Health Administration
* during this period are contractually contributed under the
* Apache License, Version 2.0.
*
* See: https://www.usa.gov/government-works
*
* Contributions prior to 2013:
*
* Copyright (C) International Health Terminology Standards Development Organisation.
* Licensed under the Apache License, Version 2.0.
*
*/
package sh.isaac.mapping.data;
//~--- JDK imports ------------------------------------------------------------
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
//~--- non-JDK imports --------------------------------------------------------
import javafx.beans.property.SimpleStringProperty;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sh.isaac.MetaData;
import sh.isaac.api.Get;
import sh.isaac.api.chronicle.LatestVersion;
import sh.isaac.api.component.concept.ConceptVersion;
import sh.isaac.api.component.sememe.SememeChronology;
import sh.isaac.api.component.sememe.SememeType;
import sh.isaac.api.component.sememe.version.DescriptionSememe;
import sh.isaac.api.component.sememe.version.DynamicSememe;
import sh.isaac.api.component.sememe.version.dynamicSememe.dataTypes.DynamicSememeString;
import sh.isaac.api.constants.DynamicSememeConstants;
import sh.isaac.api.coordinate.StampCoordinate;
import sh.isaac.api.util.StringUtils;
import sh.isaac.utility.Frills;
//~--- classes ----------------------------------------------------------------
/**
* {@link MappingSet}
*
* A Convenience class to hide unnecessary OTF bits from the Mapping APIs.
*
* @author <a href="mailto:daniel.armbrust.list@gmail.com">Dan Armbrust</a>
*/
public class MappingSet
extends MappingObject {
/** The Constant LOG. */
private static final Logger LOG = LoggerFactory.getLogger(MappingSet.class);
/** The Constant nameComparator. */
public static final Comparator<MappingSet> nameComparator =
(o1, o2) -> StringUtils.compareStringsIgnoreCase(o1.getName(),
o2.getName());
/** The Constant purposeComparator. */
public static final Comparator<MappingSet> purposeComparator =
(o1, o2) -> StringUtils.compareStringsIgnoreCase(o1.getPurpose(),
o2.getPurpose());
/** The Constant descriptionComparator. */
public static final Comparator<MappingSet> descriptionComparator =
(o1, o2) -> StringUtils.compareStringsIgnoreCase(o1.getDescription(),
o2.getDescription());
//~--- fields --------------------------------------------------------------
/** The name property. */
private final SimpleStringProperty nameProperty = new SimpleStringProperty();
/** The purpose property. */
private final SimpleStringProperty purposeProperty = new SimpleStringProperty();
/** The description property. */
private final SimpleStringProperty descriptionProperty = new SimpleStringProperty();
/** The inverse name property. */
private final SimpleStringProperty inverseNameProperty = new SimpleStringProperty();
/** The primordial UUID. */
// private String name, inverseName, description, purpose;
private UUID primordialUUID;
//~--- constructors --------------------------------------------------------
/**
* Read an existing mapping set from the database.
*
* @param refex DynamicSememeChronicleBI<?>
* @param stampCoord the stamp coord
* @throws RuntimeException the runtime exception
*/
protected MappingSet(DynamicSememe<?> refex, StampCoordinate stampCoord)
throws RuntimeException {
this.readFromRefex(refex, stampCoord); // Sets Name, inverseName and Description, etc
}
//~--- methods -------------------------------------------------------------
/**
* Read from refex.
*
* @param refex the refex
* @param stampCoord the stamp coord
* @throws RuntimeException the runtime exception
*/
private void readFromRefex(DynamicSememe<?> refex, StampCoordinate stampCoord)
throws RuntimeException {
final Optional<ConceptVersion<?>> mappingConcept = MappingSetDAO.getMappingConcept(refex, stampCoord);
if (mappingConcept.isPresent()) {
this.primordialUUID = mappingConcept.get()
.getPrimordialUuid();
readStampDetails(mappingConcept.get());
// setEditorStatusConcept((refex.getData().length > 0 && refex.getData()[0] != null ? ((DynamicSememeUUID) refex.getData()[0]).getDataUUID() : null));
if ((refex.getData().length > 0) && (refex.getData()[0] != null)) {
setPurpose(((DynamicSememeString) refex.getData()[0]).getDataString());
}
Get.sememeService().getSememesForComponent(mappingConcept.get()
.getNid()).filter(s -> s.getSememeType() == SememeType.DESCRIPTION).forEach(descriptionC -> {
if ((getName() != null) && (getDescription() != null) && (getInverseName() != null)) {
// noop... sigh... can't short-circuit in a forEach....
} else {
@SuppressWarnings({ "rawtypes", "unchecked" })
final Optional<LatestVersion<DescriptionSememe<?>>> latest =
((SememeChronology) descriptionC).getLatestVersion(DescriptionSememe.class, stampCoord);
// TODO handle contradictions
if (latest.isPresent()) {
final DescriptionSememe<?> ds = latest.get()
.value();
if (ds.getDescriptionTypeConceptSequence() == MetaData.SYNONYM.getConceptSequence()) {
if (Frills.isDescriptionPreferred(ds.getNid(), null)) {
setName(ds.getText());
} else
// see if it is the inverse name
{
if (Get.sememeService()
.getSememesForComponentFromAssemblage(ds.getNid(),
DynamicSememeConstants.get().DYNAMIC_SEMEME_ASSOCIATION_INVERSE_NAME
.getSequence())
.anyMatch(sememeC -> {
return sememeC.isLatestVersionActive(stampCoord);
})) {
setInverseName(ds.getText());
}
}
} else if (ds.getDescriptionTypeConceptSequence() ==
MetaData.DEFINITION_DESCRIPTION_TYPE.getConceptSequence()) {
if (Frills.isDescriptionPreferred(ds.getNid(), null)) {
setDescription(ds.getText());
}
}
}
}
});
} else {
final String error = "cannot read mapping concept!";
LOG.error(error);
throw new RuntimeException(error);
}
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the comments.
*
* @param stampCoord the stamp coord
* @return Any comments attached to this mapping set.
* @throws RuntimeException the runtime exception
*/
public List<MappingItemComment> getComments(StampCoordinate stampCoord)
throws RuntimeException {
return MappingItemCommentDAO.getComments(getPrimordialUUID(), stampCoord);
}
/**
* Gets the description.
*
* @return - The user specified description of the mapping set.
*/
public String getDescription() {
return this.descriptionProperty.get();
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the description.
*
* @param description - specify the description of the mapping set
*/
public void setDescription(String description) {
this.descriptionProperty.set(description);
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the description property.
*
* @return the description property
*/
public SimpleStringProperty getDescriptionProperty() {
return this.descriptionProperty;
}
/**
* Gets the inverse name.
*
* @return - The inverse name of the mapping set - may return null
*/
public String getInverseName() {
return this.inverseNameProperty.get();
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the inverse name.
*
* @param inverseName - Change the inverse name of the mapping set
*/
public void setInverseName(String inverseName) {
this.inverseNameProperty.set(inverseName);
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the inverse name property.
*
* @return the inverse name property
*/
public SimpleStringProperty getInverseNameProperty() {
return this.inverseNameProperty;
}
/**
* Gets the mapping items.
*
* @param stampCoord the stamp coord
* @return the mapping items
*/
public List<MappingItem> getMappingItems(StampCoordinate stampCoord) {
List<MappingItem> mappingItems = null;
try {
mappingItems = MappingItemDAO.getMappingItems(this.getPrimordialUUID(), stampCoord);
} catch (final Exception e) {
LOG.error("Error retrieving Mapping Items for " + this.getName(), e);
mappingItems = new ArrayList<>();
}
return mappingItems;
}
/**
* Gets the name.
*
* @return the name of the mapping set
*/
public String getName() {
return this.nameProperty.get();
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the name.
*
* @param name - Change the name of the mapping set
*/
public void setName(String name) {
this.nameProperty.set(name);
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the name property.
*
* @return the name property
*/
public SimpleStringProperty getNameProperty() {
return this.nameProperty;
}
/**
* Gets the primordial UUID.
*
* @return the identifier of this mapping set
*/
public UUID getPrimordialUUID() {
return this.primordialUUID;
}
/**
* Gets the purpose.
*
* @return - the 'purpose' of the mapping set - may be null
*/
public String getPurpose() {
return this.purposeProperty.get();
}
//~--- set methods ---------------------------------------------------------
/**
* Sets the purpose.
*
* @param purpose - The 'purpose' of the mapping set. May specify null.
*/
public void setPurpose(String purpose) {
this.purposeProperty.set(purpose);
}
//~--- get methods ---------------------------------------------------------
/**
* Gets the purpose property.
*
* @return the purpose property
*/
public SimpleStringProperty getPurposeProperty() {
return this.purposeProperty;
}
/**
* Gets the summary.
*
* @param stampCoord the stamp coord
* @return The summary of the mapping set
*/
public String getSummary(StampCoordinate stampCoord) {
List<MappingItem> mappingItems;
mappingItems = this.getMappingItems(stampCoord);
return Integer.toString(mappingItems.size()) + " Mapping Items";
}
}