/* * 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.provider.coordinate; //~--- JDK imports ------------------------------------------------------------ import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.temporal.TemporalAccessor; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; import java.util.Optional; import java.util.stream.IntStream; import java.util.stream.Stream; import javax.inject.Singleton; //~--- non-JDK imports -------------------------------------------------------- import org.jvnet.hk2.annotations.Service; import sh.isaac.api.Get; import sh.isaac.api.State; import sh.isaac.api.bootstrap.TermAux; import sh.isaac.api.chronicle.LatestVersion; import sh.isaac.api.component.concept.ConceptSpecification; import sh.isaac.api.component.sememe.SememeChronology; import sh.isaac.api.component.sememe.SememeSnapshotService; import sh.isaac.api.component.sememe.version.ComponentNidSememe; import sh.isaac.api.component.sememe.version.DescriptionSememe; import sh.isaac.api.coordinate.CoordinateFactory; import sh.isaac.api.coordinate.EditCoordinate; import sh.isaac.api.coordinate.LanguageCoordinate; import sh.isaac.api.coordinate.LogicCoordinate; import sh.isaac.api.coordinate.StampCoordinate; import sh.isaac.api.coordinate.StampPrecedence; import sh.isaac.api.coordinate.TaxonomyCoordinate; import sh.isaac.model.configuration.EditCoordinates; import sh.isaac.model.configuration.LanguageCoordinates; import sh.isaac.model.configuration.LogicCoordinates; import sh.isaac.model.configuration.StampCoordinates; import sh.isaac.model.configuration.TaxonomyCoordinates; import sh.isaac.model.coordinate.StampCoordinateImpl; import sh.isaac.model.coordinate.StampPositionImpl; //~--- classes ---------------------------------------------------------------- /** * The Class CoordinateFactoryProvider. * * @author kec */ @Service @Singleton public class CoordinateFactoryProvider implements CoordinateFactory { /** * Case significance to concept sequence. * * @param initialCaseSignificant the initial case significant * @return the int */ @Override public int caseSignificanceToConceptSequence(boolean initialCaseSignificant) { return LanguageCoordinates.caseSignificanceToConceptSequence(initialCaseSignificant); } /** * Concept id to case significance. * * @param id the id * @return true, if successful */ @Override public boolean conceptIdToCaseSignificance(int id) { return LanguageCoordinates.conceptIdToCaseSignificance(id); } /** * Concept id to iso 639. * * @param nid the nid * @return the string */ @Override public String conceptIdToIso639(int nid) { return LanguageCoordinates.conceptNidToIso639(nid); } /** * Creates the classifier solor overlay edit coordinate. * * @return the edits the coordinate */ @Override public EditCoordinate createClassifierSolorOverlayEditCoordinate() { return EditCoordinates.getClassifierSolorOverlay(); } /** * Creates the default inferred taxonomy coordinate. * * @return the taxonomy coordinate */ @Override public TaxonomyCoordinate createDefaultInferredTaxonomyCoordinate() { return createInferredTaxonomyCoordinate(createDevelopmentLatestActiveOnlyStampCoordinate(), getUsEnglishLanguageFullySpecifiedNameCoordinate(), createStandardElProfileLogicCoordinate()); } /** * Creates the default stated taxonomy coordinate. * * @return the taxonomy coordinate */ @Override public TaxonomyCoordinate createDefaultStatedTaxonomyCoordinate() { return createStatedTaxonomyCoordinate(createDevelopmentLatestActiveOnlyStampCoordinate(), getUsEnglishLanguageFullySpecifiedNameCoordinate(), createStandardElProfileLogicCoordinate()); } /** * Creates the default user metadata edit coordinate. * * @return the edits the coordinate */ @Override public EditCoordinate createDefaultUserMetadataEditCoordinate() { return EditCoordinates.getDefaultUserMetadata(); } /** * Creates the default user solor overlay edit coordinate. * * @return the edits the coordinate */ @Override public EditCoordinate createDefaultUserSolorOverlayEditCoordinate() { return EditCoordinates.getDefaultUserSolorOverlay(); } /** * Creates the default user veterans administration extension edit coordinate. * * @return the edits the coordinate */ @Override public EditCoordinate createDefaultUserVeteransAdministrationExtensionEditCoordinate() { return EditCoordinates.getDefaultUserVeteransAdministrationExtension(); } /** * Creates the development latest active only stamp coordinate. * * @return the stamp coordinate */ @Override public StampCoordinate createDevelopmentLatestActiveOnlyStampCoordinate() { return StampCoordinates.getDevelopmentLatestActiveOnly(); } /** * Creates the development latest stamp coordinate. * * @return the stamp coordinate */ @Override public StampCoordinate createDevelopmentLatestStampCoordinate() { return StampCoordinates.getDevelopmentLatest(); } /** * Creates the inferred taxonomy coordinate. * * @param stampCoordinate the stamp coordinate * @param languageCoordinate the language coordinate * @param logicCoordinate the logic coordinate * @return the taxonomy coordinate */ @Override public TaxonomyCoordinate createInferredTaxonomyCoordinate(StampCoordinate stampCoordinate, LanguageCoordinate languageCoordinate, LogicCoordinate logicCoordinate) { return TaxonomyCoordinates.getInferredTaxonomyCoordinate(stampCoordinate, languageCoordinate, logicCoordinate); } /** * Creates the master latest active only stamp coordinate. * * @return the stamp coordinate */ @Override public StampCoordinate createMasterLatestActiveOnlyStampCoordinate() { return StampCoordinates.getMasterLatestActiveOnly(); } /** * Creates the master latest stamp coordinate. * * @return the stamp coordinate */ @Override public StampCoordinate createMasterLatestStampCoordinate() { return StampCoordinates.getMasterLatest(); } /** * Creates the stamp coordinate. * * @param stampPath the stamp path * @param precedence the precedence * @param moduleSpecificationList the module specification list * @param allowedStateSet the allowed state set * @param dateTimeText the date time text * @return the stamp coordinate */ @Override public StampCoordinate createStampCoordinate(ConceptSpecification stampPath, StampPrecedence precedence, List<ConceptSpecification> moduleSpecificationList, EnumSet<State> allowedStateSet, CharSequence dateTimeText) { final StampPositionImpl stampPosition = new StampPositionImpl(LocalDateTime.parse(dateTimeText).toEpochSecond(ZoneOffset.UTC), stampPath.getConceptSequence()); return new StampCoordinateImpl(precedence, stampPosition, moduleSpecificationList, allowedStateSet); } /** * Creates the stamp coordinate. * * @param stampPath the stamp path * @param precedence the precedence * @param moduleSpecificationList the module specification list * @param allowedStateSet the allowed state set * @param temporal the temporal * @return the stamp coordinate */ @Override public StampCoordinate createStampCoordinate(ConceptSpecification stampPath, StampPrecedence precedence, List<ConceptSpecification> moduleSpecificationList, EnumSet<State> allowedStateSet, TemporalAccessor temporal) { final StampPositionImpl stampPosition = new StampPositionImpl(LocalDateTime.from(temporal).toEpochSecond(ZoneOffset.UTC), stampPath.getConceptSequence()); return new StampCoordinateImpl(precedence, stampPosition, moduleSpecificationList, allowedStateSet); } /** * Creates the stamp coordinate. * * @param stampPath the stamp path * @param precedence the precedence * @param moduleSpecificationList the module specification list * @param allowedStateSet the allowed state set * @param year the year * @param month the month * @param dayOfMonth the day of month * @param hour the hour * @param minute the minute * @param second the second * @return the stamp coordinate */ @Override public StampCoordinate createStampCoordinate(ConceptSpecification stampPath, StampPrecedence precedence, List<ConceptSpecification> moduleSpecificationList, EnumSet<State> allowedStateSet, int year, int month, int dayOfMonth, int hour, int minute, int second) { final StampPositionImpl stampPosition = new StampPositionImpl(LocalDateTime.of(year, month, dayOfMonth, hour, minute, second).toEpochSecond( ZoneOffset.UTC), stampPath.getConceptSequence()); return new StampCoordinateImpl(precedence, stampPosition, moduleSpecificationList, allowedStateSet); } /** * Creates the standard el profile logic coordinate. * * @return the logic coordinate */ @Override public LogicCoordinate createStandardElProfileLogicCoordinate() { return LogicCoordinates.getStandardElProfile(); } /** * Creates the stated taxonomy coordinate. * * @param stampCoordinate the stamp coordinate * @param languageCoordinate the language coordinate * @param logicCoordinate the logic coordinate * @return the taxonomy coordinate */ @Override public TaxonomyCoordinate createStatedTaxonomyCoordinate(StampCoordinate stampCoordinate, LanguageCoordinate languageCoordinate, LogicCoordinate logicCoordinate) { return TaxonomyCoordinates.getStatedTaxonomyCoordinate(stampCoordinate, languageCoordinate, logicCoordinate); } /** * Iso 639 to concept nid. * * @param iso639text the iso 639 text * @return the int */ @Override public int iso639toConceptNid(String iso639text) { return LanguageCoordinates.iso639toConceptNid(iso639text); } /** * Iso 639 to concept sequence. * * @param iso639text the iso 639 text * @return the int */ @Override public int iso639toConceptSequence(String iso639text) { return LanguageCoordinates.iso639toConceptSequence(iso639text); } //~--- get methods --------------------------------------------------------- /** * Gets the acceptable concept sequence. * * @return the acceptable concept sequence */ @Override public int getAcceptableConceptSequence() { return TermAux.ACCEPTABLE.getConceptSequence(); } /** * Gets the fully specified concept sequence. * * @return the fully specified concept sequence */ @Override public int getFullySpecifiedConceptSequence() { return TermAux.FULLY_SPECIFIED_DESCRIPTION_TYPE.getConceptSequence(); } /** * Gets the gb english language fully specified name coordinate. * * @return the gb english language fully specified name coordinate */ public static LanguageCoordinate getGbEnglishLanguageFullySpecifiedNameCoordinate() { return LanguageCoordinates.getGbEnglishLanguageFullySpecifiedNameCoordinate(); } /** * Gets the gb english language preferred term coordinate. * * @return the gb english language preferred term coordinate */ @Override public LanguageCoordinate getGbEnglishLanguagePreferredTermCoordinate() { return LanguageCoordinates.getGbEnglishLanguagePreferredTermCoordinate(); } /** * Gets the preferred concept sequence. * * @return the preferred concept sequence */ @Override public int getPreferredConceptSequence() { return TermAux.PREFERRED.getConceptSequence(); } /** * Gets the specified description. * * @param stampCoordinate the stamp coordinate * @param descriptionList the description list * @param languageCoordinate the language coordinate * @return the specified description */ @Override public Optional<LatestVersion<DescriptionSememe<?>>> getSpecifiedDescription(StampCoordinate stampCoordinate, List<SememeChronology<? extends DescriptionSememe<?>>> descriptionList, LanguageCoordinate languageCoordinate) { for (final int descType: languageCoordinate.getDescriptionTypePreferenceList()) { final Optional<LatestVersion<DescriptionSememe<?>>> match = getSpecifiedDescription(stampCoordinate, descriptionList, descType, languageCoordinate); if (match.isPresent()) { return match; } } return Optional.empty(); } /** * Gets the specified description. * * @param stampCoordinate the stamp coordinate * @param descriptionList the description list * @param typeSequence the type sequence * @param languageCoordinate the language coordinate * @return the specified description */ @Override public Optional<LatestVersion<DescriptionSememe<?>>> getSpecifiedDescription(StampCoordinate stampCoordinate, List<SememeChronology<? extends DescriptionSememe<?>>> descriptionList, int typeSequence, LanguageCoordinate languageCoordinate) { final SememeSnapshotService<ComponentNidSememe> acceptabilitySnapshot = Get.sememeService() .getSnapshot(ComponentNidSememe.class, stampCoordinate); final List<DescriptionSememe<?>> descriptionsForLanguageOfType = new ArrayList<>(); descriptionList.stream().forEach((descriptionChronicle) -> { @SuppressWarnings("unchecked") final Optional<LatestVersion<DescriptionSememe<?>>> latestDescription = ((SememeChronology) descriptionChronicle).getLatestVersion(DescriptionSememe.class, stampCoordinate); if (latestDescription.isPresent()) { final LatestVersion<DescriptionSememe<?>> latestDescriptionVersion = latestDescription.get(); latestDescriptionVersion.versionStream().forEach((descriptionVersion) -> { if (descriptionVersion.getLanguageConceptSequence() == languageCoordinate.getLanguageConceptSequence()) { if (descriptionVersion.getDescriptionTypeConceptSequence() == typeSequence) { descriptionsForLanguageOfType.add(descriptionVersion); } } }); } }); if (descriptionsForLanguageOfType.isEmpty()) { return Optional.empty(); } // handle dialect... final LatestVersion<DescriptionSememe<?>> preferredForDialect = new LatestVersion(DescriptionSememe.class); IntStream.of(languageCoordinate.getDialectAssemblagePreferenceList()).forEach((dialectAssemblageSequence) -> { if (preferredForDialect.value() == null) { descriptionsForLanguageOfType.forEach((DescriptionSememe description) -> { final Stream<LatestVersion<ComponentNidSememe>> acceptability = acceptabilitySnapshot.getLatestSememeVersionsForComponentFromAssemblage(description.getNid(), dialectAssemblageSequence); if (acceptability.anyMatch((LatestVersion<ComponentNidSememe> acceptabilityVersion) -> { return Get.identifierService() .getConceptSequence(acceptabilityVersion.value() .getComponentNid()) == getPreferredConceptSequence(); })) { preferredForDialect.addLatest(description); } }); } }); if (preferredForDialect.value() == null) { descriptionsForLanguageOfType.forEach((fsn) -> { preferredForDialect.addLatest(fsn); }); } if (preferredForDialect.value() == null) { return Optional.empty(); } return Optional.of(preferredForDialect); } /** * Gets the synonym concept sequence. * * @return the synonym concept sequence */ @Override public int getSynonymConceptSequence() { return TermAux.SYNONYM_DESCRIPTION_TYPE.getConceptSequence(); } /** * Gets the us english language fully specified name coordinate. * * @return the us english language fully specified name coordinate */ @Override public LanguageCoordinate getUsEnglishLanguageFullySpecifiedNameCoordinate() { return LanguageCoordinates.getUsEnglishLanguageFullySpecifiedNameCoordinate(); } /** * Gets the us english language preferred term coordinate. * * @return the us english language preferred term coordinate */ @Override public LanguageCoordinate getUsEnglishLanguagePreferredTermCoordinate() { return LanguageCoordinates.getUsEnglishLanguagePreferredTermCoordinate(); } }