/* * 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.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.UUID; //~--- non-JDK imports -------------------------------------------------------- import javafx.concurrent.Task; import org.apache.commons.lang3.StringUtils; import sh.isaac.api.Get; import sh.isaac.api.State; import sh.isaac.api.chronicle.LatestVersion; import sh.isaac.api.commit.ChangeCheckerMode; import sh.isaac.api.commit.CommitRecord; import sh.isaac.api.component.sememe.SememeChronology; import sh.isaac.api.component.sememe.version.DynamicSememe; import sh.isaac.api.component.sememe.version.dynamicSememe.DynamicSememeData; import sh.isaac.api.constants.DynamicSememeConstants; import sh.isaac.api.coordinate.EditCoordinate; import sh.isaac.api.coordinate.StampCoordinate; import sh.isaac.model.sememe.dataTypes.DynamicSememeStringImpl; //~--- classes ---------------------------------------------------------------- /** * The Class MappingItemCommentDAO. */ public class MappingItemCommentDAO extends MappingDAO { /** * Create (and store to the DB) a new comment. * * @param pMappingItemUUID - The item the comment is being added to * @param pCommentText - The text of the comment * @param commentContext - (optional) field for storing other arbitrary info about the comment. An editor may wish to put certain keywords on * some comments - this field is indexed, so a search for comments could query this field. * @param stampCoord the stamp coord * @param editCoord the edit coord * @return the mapping item comment * @throws RuntimeException the runtime exception */ public static MappingItemComment createMappingItemComment(UUID pMappingItemUUID, String pCommentText, String commentContext, StampCoordinate stampCoord, EditCoordinate editCoord) throws RuntimeException { if (pMappingItemUUID == null) { throw new RuntimeException("UUID of component to attach the comment to is required"); } if (StringUtils.isBlank(pCommentText)) { throw new RuntimeException("The comment is required"); } final SememeChronology<? extends DynamicSememe<?>> built = Get.sememeBuilderService() .getDynamicSememeBuilder(Get.identifierService() .getNidForUuids(pMappingItemUUID), DynamicSememeConstants.get().DYNAMIC_SEMEME_COMMENT_ATTRIBUTE .getSequence(), new DynamicSememeData[] { new DynamicSememeStringImpl(pCommentText), (StringUtils.isBlank(commentContext) ? null : new DynamicSememeStringImpl(commentContext)) }) .build(editCoord, ChangeCheckerMode.ACTIVE) .getNoThrow(); @SuppressWarnings("deprecation") final Task<Optional<CommitRecord>> task = Get.commitService() .commit("Added comment"); try { task.get(); } catch (final Exception e) { throw new RuntimeException(); } @SuppressWarnings({ "unchecked", "rawtypes" }) final Optional<LatestVersion<DynamicSememe<?>>> latest = ((SememeChronology) built).getLatestVersion(DynamicSememe.class, stampCoord.makeAnalog(State.ACTIVE, State.INACTIVE)); return new MappingItemComment(latest.get().value()); } /** * Retire comment. * * @param commentPrimordialUUID - The ID of the comment to be retired * @param stampCoord the stamp coord * @param editCoord the edit coord * @throws IOException Signals that an I/O exception has occurred. */ public static void retireComment(UUID commentPrimordialUUID, StampCoordinate stampCoord, EditCoordinate editCoord) throws IOException { setSememeStatus(commentPrimordialUUID, State.INACTIVE, stampCoord, editCoord); } /** * Un retire comment. * * @param commentPrimordialUUID - The ID of the comment to be re-activated * @param stampCoord the stamp coord * @param editCoord the edit coord * @throws IOException Signals that an I/O exception has occurred. */ public static void unRetireComment(UUID commentPrimordialUUID, StampCoordinate stampCoord, EditCoordinate editCoord) throws IOException { setSememeStatus(commentPrimordialUUID, State.ACTIVE, stampCoord, editCoord); } /** * Store the values passed in as a new revision of a comment (the old revision remains in the DB). * * @param comment - The MappingItemComment with revisions (contains fields where the setters have been called) * @param stampCoord the stamp coord * @param editCoord the edit coord * @throws IOException Signals that an I/O exception has occurred. */ public static void updateComment(MappingItemComment comment, StampCoordinate stampCoord, EditCoordinate editCoord) throws IOException { final DynamicSememe<?> rdv = readCurrentRefex(comment.getPrimordialUUID(), stampCoord); Get.sememeBuilderService() .getDynamicSememeBuilder(rdv.getReferencedComponentNid(), DynamicSememeConstants.get().DYNAMIC_SEMEME_COMMENT_ATTRIBUTE .getSequence(), new DynamicSememeData[] { new DynamicSememeStringImpl(comment.getCommentText()), (StringUtils.isBlank(comment.getCommentContext()) ? null : new DynamicSememeStringImpl(comment.getCommentContext())) }) .build(editCoord, ChangeCheckerMode.ACTIVE); @SuppressWarnings("deprecation") final Task<Optional<CommitRecord>> task = Get.commitService() .commit("Added comment"); try { task.get(); } catch (final Exception e) { throw new RuntimeException(); } } //~--- get methods --------------------------------------------------------- /** * Read all comments for a particular mapping item (which could be a mapping set, or a mapping item). * * @param mappingUUID - The UUID of a MappingSet or a MappingItem * @param stampCoord the stamp coord * @return the comments * @throws RuntimeException the runtime exception */ public static List<MappingItemComment> getComments(UUID mappingUUID, StampCoordinate stampCoord) throws RuntimeException { final List<MappingItemComment> comments = new ArrayList<>(); Get.sememeService().getSememesForComponentFromAssemblage(Get.identifierService() .getNidForUuids(mappingUUID), DynamicSememeConstants.get().DYNAMIC_SEMEME_COMMENT_ATTRIBUTE .getSequence()).forEach(sememeC -> { @SuppressWarnings({ "unchecked", "rawtypes" }) final Optional<LatestVersion<DynamicSememe<?>>> latest = ((SememeChronology) sememeC).getLatestVersion( DynamicSememe.class, stampCoord.makeAnalog(State.ACTIVE, State.INACTIVE)); if (latest.isPresent()) { comments.add(new MappingItemComment(latest.get().value())); if (latest.get() .contradictions() .isPresent()) { // TODO handle contradictions properly latest.get() .contradictions() .get() .forEach((contradiction) -> comments.add(new MappingItemComment(contradiction))); } } }); return comments; } }