From 0577f86520a2fc005aad09034c7f3ccabc0b0fae Mon Sep 17 00:00:00 2001 From: Chris Wolf Date: Wed, 1 Jun 2022 08:14:38 -0400 Subject: [PATCH] from_version-5/fix_issue_769 - fix for settings import error along with auto-text substitution of projectIds in pasted project settings JSON from_version-5/fix_issue_769-HG-5463 - remove Slack webhook URL from unit test settings.json --- .gitignore | 19 +- .../ProjectSettingsService.java | 11 +- .../server/jackson/ObjectMapperProvider.java | 12 + .../protege/web/server/tag/TagsManager.java | 46 +- .../protege/web/server/util/JavaUtil.java | 20 + .../util/TypelessJSONSerialization.java | 94 ++++ .../stanford/bmir/protege/web/TestUtils.java | 32 ++ .../TypelessJSONSerialization_TestCase.java | 56 +++ .../server/util/project_settings_notags.json | 446 ++++++++++++++++++ 9 files changed, 719 insertions(+), 17 deletions(-) create mode 100644 webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/JavaUtil.java create mode 100644 webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization.java create mode 100644 webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/TestUtils.java create mode 100644 webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization_TestCase.java create mode 100644 webprotege-server-core/src/test/resources/edu/stanford/bmir/protege/web/server/util/project_settings_notags.json diff --git a/.gitignore b/.gitignore index 1061d9f839..3c5a35f63a 100644 --- a/.gitignore +++ b/.gitignore @@ -7,8 +7,12 @@ target/ .classpath .project .settings/ +**/.factorypath out/ +# https://www.jenv.be/ +.java-version + logs/ velocity.log.* @@ -16,4 +20,17 @@ velocity.log.* dependency-reduced-pom.xml -.protegedata/ \ No newline at end of file +.protegedata/ + +# Package Files +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* diff --git a/webprotege-client/src/main/java/edu/stanford/bmir/protege/web/client/projectsettings/ProjectSettingsService.java b/webprotege-client/src/main/java/edu/stanford/bmir/protege/web/client/projectsettings/ProjectSettingsService.java index 55a84ff346..6745ddcf7e 100644 --- a/webprotege-client/src/main/java/edu/stanford/bmir/protege/web/client/projectsettings/ProjectSettingsService.java +++ b/webprotege-client/src/main/java/edu/stanford/bmir/protege/web/client/projectsettings/ProjectSettingsService.java @@ -4,6 +4,7 @@ import com.google.gwt.resources.client.DataResource; import edu.stanford.bmir.protege.web.client.dispatch.DispatchServiceManager; import edu.stanford.bmir.protege.web.shared.project.ProjectId; +import edu.stanford.bmir.protege.web.server.util.TypelessJSONSerialization; import javax.annotation.Nonnull; import javax.inject.Inject; @@ -31,10 +32,12 @@ public ProjectSettingsService(DispatchServiceManager dispatch, ProjectId project public void importSettings(@Nonnull String settingsToImportJson, @Nonnull Runnable importSuccessfulHandler, @Nonnull Runnable importErrorHandler) { + String settingsJsonWithUpdatedProjectId; try { + settingsJsonWithUpdatedProjectId = updateInputJSONProjectId(settingsToImportJson); RequestBuilder requestBuilder = new RequestBuilder(RequestBuilder.POST, "/data/projects/" + projectId.getId() + "/settings"); - - requestBuilder.setRequestData(settingsToImportJson); + + requestBuilder.setRequestData(settingsJsonWithUpdatedProjectId); requestBuilder.setHeader("Content-Type", "application/json"); requestBuilder.setCallback(new RequestCallback() { @Override @@ -57,5 +60,9 @@ public void onError(Request request, Throwable exception) { importErrorHandler.run(); } } + + private String updateInputJSONProjectId(@Nonnull String settingsToImportJson) { + return TypelessJSONSerialization.resplaceAllStringValue(settingsToImportJson, "projectId", this.projectId.getId()); + } } diff --git a/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/jackson/ObjectMapperProvider.java b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/jackson/ObjectMapperProvider.java index 766a12f319..cdc96424ad 100644 --- a/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/jackson/ObjectMapperProvider.java +++ b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/jackson/ObjectMapperProvider.java @@ -13,10 +13,15 @@ import org.semanticweb.owlapi.model.*; import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; +import java.util.concurrent.atomic.AtomicInteger; + import javax.annotation.Nonnull; import javax.inject.Inject; import javax.inject.Provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * Matthew Horridge * Stanford Center for Biomedical Informatics Research @@ -26,7 +31,11 @@ public class ObjectMapperProvider implements Provider { @Nonnull private final OWLDataFactory dataFactory; + + private static Logger logger = LoggerFactory.getLogger(ObjectMapperProvider.class); + private static AtomicInteger mapperInstanceCount = new AtomicInteger(); + @Inject public ObjectMapperProvider() { this.dataFactory = new OWLDataFactoryImpl(); @@ -35,6 +44,9 @@ public ObjectMapperProvider() { @Override public ObjectMapper get() { ObjectMapper mapper = new ObjectMapper(); + int instanceCount = mapperInstanceCount.incrementAndGet(); + String msg = String.format("Instantiated another ObjectMappger#%08x, total: %d", mapper.hashCode(), instanceCount); + logger.info(msg); mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); mapper.setDefaultPrettyPrinter(new DefaultPrettyPrinter()); mapper.configure(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS, false); diff --git a/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/tag/TagsManager.java b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/tag/TagsManager.java index d9920cd901..a997b5ec46 100644 --- a/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/tag/TagsManager.java +++ b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/tag/TagsManager.java @@ -1,25 +1,41 @@ package edu.stanford.bmir.protege.web.server.tag; -import com.google.common.collect.Streams; -import edu.stanford.bmir.protege.web.server.events.HasPostEvents; -import edu.stanford.bmir.protege.web.shared.event.ProjectEvent; -import edu.stanford.bmir.protege.web.shared.inject.ProjectSingleton; -import edu.stanford.bmir.protege.web.shared.project.ProjectId; -import edu.stanford.bmir.protege.web.shared.tag.*; -import org.semanticweb.owlapi.model.OWLEntity; +import static com.google.common.base.Preconditions.checkNotNull; +import static edu.stanford.bmir.protege.web.shared.tag.TagId.createTagId; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static java.util.stream.Collectors.toSet; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.inject.Inject; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.stream.Stream; -import static com.google.common.base.Preconditions.checkNotNull; -import static edu.stanford.bmir.protege.web.shared.tag.TagId.createTagId; -import static java.util.stream.Collectors.*; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.inject.Inject; + +import org.semanticweb.owlapi.model.OWLEntity; + +import com.google.common.collect.Streams; + +import edu.stanford.bmir.protege.web.server.events.HasPostEvents; +import edu.stanford.bmir.protege.web.shared.event.ProjectEvent; +import edu.stanford.bmir.protege.web.shared.inject.ProjectSingleton; +import edu.stanford.bmir.protege.web.shared.project.ProjectId; +import edu.stanford.bmir.protege.web.shared.tag.EntityTagsChangedEvent; +import edu.stanford.bmir.protege.web.shared.tag.ProjectTagsChangedEvent; +import edu.stanford.bmir.protege.web.shared.tag.Tag; +import edu.stanford.bmir.protege.web.shared.tag.TagData; +import edu.stanford.bmir.protege.web.shared.tag.TagId; /** * Matthew Horridge @@ -150,6 +166,8 @@ public Collection getProjectTags() { */ public void setProjectTags(@Nonnull Collection newProjectTags) { checkNotNull(newProjectTags); + if (newProjectTags.size() == 0) + return; Collection currentProjectTags = getProjectTags(); Set modifiedEntityTags = new HashSet<>(); try { diff --git a/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/JavaUtil.java b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/JavaUtil.java new file mode 100644 index 0000000000..ac9478986d --- /dev/null +++ b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/JavaUtil.java @@ -0,0 +1,20 @@ +package edu.stanford.bmir.protege.web.server.util; + +public class JavaUtil { + /** + * The purpose of this cast utility to be able to suppress unchecked + * cast in one and only one place so we don't have to pollute the main + * application code with @SuppressWarnings and thus be able to flag + * places where the type cast warning(s) are/were unexpected. + * @param + * @param obj + * @return + * + * This great idea came from: + * @see http://www.whizu.org/articles/how-to-avoid-unchecked-cast-warnings-with-java-generics.whizu + */ + @SuppressWarnings("unchecked") + public static T cast(Object obj) { + return (T)obj; + } +} diff --git a/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization.java b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization.java new file mode 100644 index 0000000000..aeb2a4294b --- /dev/null +++ b/webprotege-server-core/src/main/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization.java @@ -0,0 +1,94 @@ +package edu.stanford.bmir.protege.web.server.util; + +import static edu.stanford.bmir.protege.web.server.util.JavaUtil.cast; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import javax.annotation.Nonnull; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.databind.ObjectWriter; + +/** + * These utility methods are for manipulating arbitrary JSON without needing to worry about what + * typed entities the JSON should be de/serialized to/from. + * + * Initial motivation is to be able to change the value of "projectId" in project settings and + * project forms import JSON. + * + * @author Chris Wolf + */ +public class TypelessJSONSerialization { + + // TODO: should probably be injected, but effects the whole upstream DI call chain... + // TODO: ...and plus, ObjectMapper very expensive, so should be created only once. + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public TypelessJSONSerialization() { + } + + /** + * Accepts any arbitrary JSON and deserializes to nested LinkedHashMap + * instances. Note that the Object type parameter could be of type String, + * List, or Map where the latter is for arbitrary nesting levels. + * + * N.B. For normal, strongly typed Webprotege serialization, use the ObjectMapper + * obtained from ObjectMapperProvider from webprotege-server-core. + * + * @param json + * @return + * @throws IOException + */ + public static Map deserializeJSON(@Nonnull String json) throws IOException { + ObjectReader objectReader = objectMapper.readerFor(new TypeReference>() { + }); + return objectReader.readValue(json); + } + + /** + * + * @param object + * @return + * @throws IOException + */ + public static String serializeToJSON(Map object) throws IOException { + return serializeToJSON(object, false); + } + + public static String serializeToJSON(Map object, boolean prettyPrint) throws IOException { + ObjectWriter objectWriter = prettyPrint ? objectMapper.writerWithDefaultPrettyPrinter() : objectMapper.writer(); + return objectWriter.writeValueAsString(object); + } + + public static String resplaceAllStringValue(@Nonnull String json, @Nonnull String keyName, + @Nonnull String replacementValue) throws IOException { + + Map deserialized = deserializeJSON(json); + + walkMapAndDReplace(deserialized, keyName, replacementValue); + + String serialized = serializeToJSON(deserialized); + + return serialized; + } + + static void walkMapAndDReplace(Map data, String keyName, String replacementValue) { + for (var mapEntry : data.entrySet()) { + if (mapEntry.getValue() instanceof String && mapEntry.getKey().equals(keyName)) { + mapEntry.setValue(replacementValue); + } else if (mapEntry.getValue() instanceof List) { + List objlist = cast(mapEntry.getValue()); + for (Object listEntry : objlist) { + if (listEntry instanceof Map) + walkMapAndDReplace(cast(listEntry), keyName, replacementValue); + } + } else if (mapEntry.getValue() instanceof Map) { + walkMapAndDReplace(cast(mapEntry.getValue()), keyName, replacementValue); + } + } + } +} diff --git a/webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/TestUtils.java b/webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/TestUtils.java new file mode 100644 index 0000000000..08d4f09601 --- /dev/null +++ b/webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/TestUtils.java @@ -0,0 +1,32 @@ +package edu.stanford.bmir.protege.web; + +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class TestUtils { + /** + * Read contents of text file resource from src/test/resources. + * Entire content read into memory, so best for small files. + * + * @param resourceName + * @return text content and assuming UTF-8 encoding + * @throws IOException + */ + public static String readResourceTestFile(String resourceName) throws IOException { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + URI resource; + try { + resource = classLoader.getResource(resourceName).toURI(); + } catch (URISyntaxException e) { + String msg = String.format("Can't read '%s'", resourceName); + throw new IOException(msg, e); + } + byte[] rawContent = Files.readAllBytes(Paths.get(resource)); + + return new String(rawContent, StandardCharsets.UTF_8); + } +} diff --git a/webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization_TestCase.java b/webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization_TestCase.java new file mode 100644 index 0000000000..32f7210869 --- /dev/null +++ b/webprotege-server-core/src/test/java/edu/stanford/bmir/protege/web/server/util/TypelessJSONSerialization_TestCase.java @@ -0,0 +1,56 @@ +package edu.stanford.bmir.protege.web.server.util; + +import static edu.stanford.bmir.protege.web.server.util.JavaUtil.cast; +import static org.junit.Assert.assertEquals; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.junit.MockitoJUnitRunner.Silent; + +import edu.stanford.bmir.protege.web.TestUtils; +import edu.stanford.bmir.protege.web.shared.project.ProjectId; + +@RunWith(Silent.class) +public class TypelessJSONSerialization_TestCase { + private ProjectId projectId = ProjectId.get("c4e39f8f-d2b3-4212-8888-28fabd2aa5ac"); + + @Test + public void testJSONSerialization() throws Exception { + // test basic round-trip deserialize/serialize + + String testSettings = TestUtils + .readResourceTestFile("edu/stanford/bmir/protege/web/server/util/project_settings_notags.json"); + // out.println(testSettings); + Map data = TypelessJSONSerialization.deserializeJSON(testSettings); + + String newSettings = TypelessJSONSerialization.serializeToJSON(data, true); + + assertEquals(StringUtils.deleteWhitespace(testSettings), StringUtils.deleteWhitespace(newSettings)); + // out.println(newSettings); + } + + @Test + public void testJSONSerializationNameValueReplacement() throws Exception { + String testSettings = TestUtils + .readResourceTestFile("edu/stanford/bmir/protege/web/server/util/project_settings_notags.json"); + + String newSettings = TypelessJSONSerialization.resplaceAllStringValue(testSettings, "projectId", + projectId.getId()); + Map data = TypelessJSONSerialization.deserializeJSON(newSettings); + + String id = projectId.getId(); + Map projectSettings = cast(data.get("projectSettings")); + Map sharingSettings = cast(data.get("sharingSettings")); + Map searchSettings = cast(data.get("searchSettings")); + List> searchFilters = cast(searchSettings.get("searchFilters")); + + assertEquals(id, projectSettings.get("projectId")); + assertEquals(id, sharingSettings.get("projectId")); + assertEquals(id, searchSettings.get("projectId")); + assertEquals(id, searchFilters.get(0).get("projectId")); + } +} diff --git a/webprotege-server-core/src/test/resources/edu/stanford/bmir/protege/web/server/util/project_settings_notags.json b/webprotege-server-core/src/test/resources/edu/stanford/bmir/protege/web/server/util/project_settings_notags.json new file mode 100644 index 0000000000..486d9f0131 --- /dev/null +++ b/webprotege-server-core/src/test/resources/edu/stanford/bmir/protege/web/server/util/project_settings_notags.json @@ -0,0 +1,446 @@ +{ + "projectSettings": { + "projectId": "00000000-0000-0000-0000-000000000000", + "displayName": "H-Graph", + "description": "", + "defaultLanguage": { + "type": "AnnotationAssertion", + "propertyIri": "rdfs:label" + }, + "defaultDisplayNameSettings": { + "primaryDisplayNameLanguages": [ + { + "type": "AnnotationAssertion", + "lang": "en", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertion", + "lang": "es", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertion", + "lang": "fr", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertion", + "lang": "de", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertion", + "lang": "pt-br", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertion", + "lang": "zh", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertion", + "propertyIri": "rdfs:label" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasMN", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "en" + }, + { + "type": "LocalName" + }, + { + "type": "PrefixedName" + }, + { + "type": "AnnotationAssertion", + "propertyIri": "https://data.elsevier.com/health/core/schema/hasImui" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasCFN", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "en" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasSyn", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "en" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasSyn", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "es" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasSyn", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "fr" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasSyn", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "de" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasSyn", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "pt-BR" + }, + { + "type": "AnnotationAssertionPath", + "path": [ + "https://data.elsevier.com/health/core/schema/hasSyn", + "http://www.w3.org/2000/01/rdf-schema#label" + ], + "lang": "zh" + } + ], + "secondaryDisplayNameLanguages": [] + }, + "slackIntegrationSettings": { + "payloadUrl": "https://localhost/dummyfake" + }, + "webhookSettings": { + "webhookSettings": [] + }, + "entityDeprecationSettings": { + "replacedByFilter": null, + "replacedByPropertyIri": null, + "deprecatedClassesParent": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/RetiredConcept" + }, + "deprecatedObjectPropertiesParent": null, + "deprecatedDataPropertiesParent": null, + "deprecatedAnnotationPropertiesParent": null, + "deprecatedIndividualsParent": null + } + }, + "entityCreationSettings": { + "prefixSettings": { + "conditionalIriPrefixes": [ + { + "iriPrefix": "https://data.elsevier.com/health/core/concept/", + "criteria": { + "match": "CompositeCriteria", + "matchType": "ALL", + "criteria": [ + { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Concept" + }, + "filterType": "ALL" + } + ] + } + }, + { + "iriPrefix": "https://data.elsevier.com/health/core/schema/", + "criteria": { + "match": "CompositeCriteria", + "matchType": "ALL", + "criteria": [ + { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Relation" + }, + "filterType": "DIRECT" + }, + { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Term" + }, + "filterType": "DIRECT" + } + ] + } + }, + { + "iriPrefix": "https://data.elsevier.com/health/core/relation/", + "criteria": { + "match": "CompositeCriteria", + "matchType": "ALL", + "criteria": [ + { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Relation" + }, + "filterType": "ALL" + } + ] + } + }, + { + "iriPrefix": "https://data.elsevier.com/health/core/term/", + "criteria": { + "match": "CompositeCriteria", + "matchType": "ALL", + "criteria": [ + { + "match": "InstanceOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Term" + }, + "filterType": "ALL" + } + ] + } + }, + { + "iriPrefix": "https://data.elsevier.com/health/core/relation/", + "criteria": { + "match": "CompositeCriteria", + "matchType": "ALL", + "criteria": [ + { + "match": "InstanceOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Relation" + }, + "filterType": "ALL" + } + ] + } + }, + { + "iriPrefix": "https://data.elsevier.com/health/core/mapping/UMLS/", + "criteria": { + "match": "CompositeCriteria", + "matchType": "ALL", + "criteria": [ + { + "match": "InstanceOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/UMLS" + }, + "filterType": "DIRECT" + } + ] + } + } + ], + "iriPrefix": "https://data.elsevier.com/health/core/" + }, + "suffixSettings": { + "_class": "Uuid", + "uuidFormat": "STANDARD" + }, + "generatedAnnotationsSettings": { + "descriptors": [ + { + "property": { + "type": "owl:AnnotationProperty", + "iri": "https://data.elsevier.com/health/core/schema/hasImui" + }, + "value": { + "@type": "IncrementingPattern", + "startingValue": 10000000, + "format": "" + }, + "activatedBy": { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/concept/id-cccc5330-7d23-35e9-a9f5-fc62b59aeeda" + }, + "filterType": "ALL" + } + } + ] + } + }, + "prefixDeclarations": [], + "projectTags": [], + "sharingSettings": { + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "sharingSettings": [ + { + "personId": "Fred Flintstone", + "sharingPermission": "EDIT" + }, + { + "personId": "Roades", + "sharingPermission": "VIEW" + }, + { + "personId": "uberuser", + "sharingPermission": "MANAGE" + } + ], + "linkSharingPermission": null + }, + "searchSettings": { + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "searchFilters": [ + { + "_id": "6166eefe-39f8-408c-ae74-58a04b445dfe", + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "label": { + "en": "Concepts" + }, + "criteria": { + "match": "CompositeCriteria", + "criteria": [ + { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Concept" + }, + "filterType": "ALL" + } + ], + "matchType": "ALL" + } + }, + { + "_id": "dab3e204-3e9a-401e-aca6-a659583effe7", + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "label": { + "en": "Drugs" + }, + "criteria": { + "match": "CompositeCriteria", + "criteria": [ + { + "match": "EntityRelationship", + "presence": "AT_LEAST_ONE", + "property": { + "match": "PropertyEquals", + "property": { + "type": "owl:ObjectProperty", + "iri": "https://data.elsevier.com/health/core/schema/hasSty" + } + }, + "value": { + "match": "ValueEqualToEntity", + "value": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/id-5cc97031-dac3-3c38-835f-a4de1c207f4d" + } + } + } + ], + "matchType": "ALL" + } + }, + { + "_id": "1974dc30-d9e9-4b9d-961d-5f3b3fbe5f77", + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "label": { + "en": "Diseases" + }, + "criteria": { + "match": "CompositeCriteria", + "criteria": [ + { + "match": "EntityRelationship", + "presence": "AT_LEAST_ONE", + "property": { + "match": "PropertyEquals", + "property": { + "type": "owl:ObjectProperty", + "iri": "https://data.elsevier.com/health/core/schema/hasSty" + } + }, + "value": { + "match": "ValueEqualToEntity", + "value": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/id-ed318c77-e1bc-3b91-aada-7a1c35b64c25" + } + } + } + ], + "matchType": "ALL" + } + }, + { + "_id": "a77074c8-9b64-43fe-be60-4126868934b0", + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "label": { + "en": "Organisms" + }, + "criteria": { + "match": "CompositeCriteria", + "criteria": [ + { + "match": "EntityRelationship", + "presence": "AT_LEAST_ONE", + "property": { + "match": "PropertyEquals", + "property": { + "type": "owl:ObjectProperty", + "iri": "https://data.elsevier.com/health/core/schema/hasSty" + } + }, + "value": { + "match": "ValueEqualToEntity", + "value": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/id-eb5d93da-a896-3a27-a2a7-5d6cd3458047" + } + } + } + ], + "matchType": "ALL" + } + }, + { + "_id": "4b578004-3a90-4ae3-a710-5f8a2e9b1e09", + "projectId": "ff079d1f-9bb8-4b2d-9d1f-59940722b863", + "label": { + "en": "Relations" + }, + "criteria": { + "match": "CompositeCriteria", + "criteria": [ + { + "match": "SubClassOf", + "target": { + "type": "owl:Class", + "iri": "https://data.elsevier.com/health/core/schema/Relation" + }, + "filterType": "ALL" + } + ], + "matchType": "ALL" + } + } + ] + } +}