001package ca.uhn.fhir.jpa.entity;
002
003/*-
004 * #%L
005 * HAPI FHIR JPA Server
006 * %%
007 * Copyright (C) 2014 - 2021 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import org.hibernate.search.engine.backend.document.DocumentElement;
024import org.hibernate.search.engine.backend.document.model.dsl.IndexSchemaElement;
025import org.hibernate.search.mapper.pojo.bridge.PropertyBridge;
026import org.hibernate.search.mapper.pojo.bridge.binding.PropertyBindingContext;
027import org.hibernate.search.mapper.pojo.bridge.mapping.programmatic.PropertyBinder;
028import org.hibernate.search.mapper.pojo.bridge.runtime.PropertyBridgeWriteContext;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032import java.util.Collection;
033
034import static org.apache.commons.lang3.StringUtils.isNotBlank;
035
036/**
037 * Allows hibernate search to index individual concepts' properties
038 */
039public class TermConceptPropertyBinder implements PropertyBinder {
040
041
042        public static final String CONCEPT_FIELD_PROPERTY_PREFIX = "PROP";
043        private static final Logger ourLog = LoggerFactory.getLogger(TermConceptPropertyBinder.class);
044
045        @Override
046        public void bind(PropertyBindingContext thePropertyBindingContext) {
047                thePropertyBindingContext.dependencies().use("myKey").use("myValue");
048                IndexSchemaElement indexSchemaElement = thePropertyBindingContext.indexSchemaElement();
049
050                //In order to support dynamic fields, we have to use field templates. We _must_ define the template at bootstrap time and cannot
051                //create them adhoc. https://docs.jboss.org/hibernate/search/6.0/reference/en-US/html_single/#mapper-orm-bridge-index-field-dsl-dynamic
052                //I _think_ im doing the right thing here by indicating that everything matching this template uses this analyzer.
053                indexSchemaElement.fieldTemplate("propTemplate", f -> f.asString().analyzer("termConceptPropertyAnalyzer"))
054                        .matchingPathGlob(CONCEPT_FIELD_PROPERTY_PREFIX + "*")
055                        .multiValued();
056
057
058                thePropertyBindingContext.bridge(new TermConceptPropertyBridge());
059        }
060
061        private class TermConceptPropertyBridge implements PropertyBridge {
062
063                @Override
064                public void write(DocumentElement theDocument, Object theObject, PropertyBridgeWriteContext thePropertyBridgeWriteContext) {
065
066                        Collection<TermConceptProperty> properties = (Collection<TermConceptProperty>) theObject;
067
068                        if (properties != null) {
069                                for (TermConceptProperty next : properties) {
070                                        theDocument.addValue(CONCEPT_FIELD_PROPERTY_PREFIX + next.getKey(), next.getValue());
071                                        ourLog.trace("Adding Prop: {}{} -- {}", CONCEPT_FIELD_PROPERTY_PREFIX, next.getKey(), next.getValue());
072                                        if (next.getType() == TermConceptPropertyTypeEnum.CODING && isNotBlank(next.getDisplay())) {
073                                                theDocument.addValue(CONCEPT_FIELD_PROPERTY_PREFIX + next.getKey(), next.getDisplay());
074                                                ourLog.trace("Adding multivalue Prop: {}{} -- {}", CONCEPT_FIELD_PROPERTY_PREFIX, next.getKey(), next.getDisplay());
075                                        }
076                                }
077                        }
078                }
079        }
080}