001package ca.uhn.fhir.util;
002
003/*-
004 * #%L
005 * HAPI FHIR - Core Library
006 * %%
007 * Copyright (C) 2014 - 2019 University Health Network
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 ca.uhn.fhir.context.BaseRuntimeChildDefinition;
024import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
025import ca.uhn.fhir.context.FhirContext;
026import org.hl7.fhir.instance.model.api.IBase;
027import org.hl7.fhir.instance.model.api.ICompositeType;
028import org.hl7.fhir.instance.model.api.IPrimitiveType;
029
030import java.util.List;
031
032public class AttachmentUtil {
033
034        /**
035         * Fetches the base64Binary value of Attachment.data, creating it if it does not
036         * already exist.
037         */
038        @SuppressWarnings("unchecked")
039        public static IPrimitiveType<byte[]> getOrCreateData(FhirContext theContext, ICompositeType theAttachment) {
040                return getOrCreateChild(theContext, theAttachment, "data", "base64Binary");
041        }
042
043        @SuppressWarnings("unchecked")
044        public static IPrimitiveType<String> getOrCreateContentType(FhirContext theContext, ICompositeType theAttachment) {
045                return getOrCreateChild(theContext, theAttachment, "contentType", "string");
046        }
047
048        public static IPrimitiveType<String> getOrCreateUrl(FhirContext theContext, ICompositeType theAttachment) {
049                return getOrCreateChild(theContext, theAttachment, "url", "uri");
050        }
051
052        @SuppressWarnings("unchecked")
053        private static <T> IPrimitiveType<T> getOrCreateChild(FhirContext theContext, ICompositeType theAttachment, String theChildName, String theChildDatatype) {
054                BaseRuntimeChildDefinition entryChild = getChild(theContext, theAttachment, theChildName);
055                List<IBase> entries = entryChild.getAccessor().getValues(theAttachment);
056                return entries
057                        .stream()
058                        .map(t -> (IPrimitiveType<T>) t)
059                        .findFirst()
060                        .orElseGet(() -> {
061                                IPrimitiveType<String> string = newPrimitive(theContext, theChildDatatype, null);
062                                entryChild.getMutator().setValue(theAttachment, string);
063                                return (IPrimitiveType<T>) string;
064                        });
065        }
066
067        public static void setContentType(FhirContext theContext, ICompositeType theAttachment, String theContentType) {
068                BaseRuntimeChildDefinition entryChild = getChild(theContext, theAttachment, "contentType");
069                entryChild.getMutator().setValue(theAttachment, newPrimitive(theContext, "code", theContentType));
070        }
071
072        public static void setData(FhirContext theContext, ICompositeType theAttachment, byte[] theBytes) {
073                BaseRuntimeChildDefinition entryChild = getChild(theContext, theAttachment, "data");
074                entryChild.getMutator().setValue(theAttachment, newPrimitive(theContext, "base64Binary", theBytes));
075        }
076
077        public static void setSize(FhirContext theContext, ICompositeType theAttachment, Integer theLength) {
078                BaseRuntimeChildDefinition entryChild = getChild(theContext, theAttachment, "size");
079                if (theLength == null) {
080                        entryChild.getMutator().setValue(theAttachment, null);
081                } else {
082                        entryChild.getMutator().setValue(theAttachment, newPrimitive(theContext, "unsignedInt", theLength));
083                }
084        }
085
086        /**
087         * This is internal API- Use with caution as it may change
088         */
089        @SuppressWarnings("unchecked")
090        static <T> IPrimitiveType<T> newPrimitive(FhirContext theContext, String theType, T theValue) {
091                IPrimitiveType<T> primitive = (IPrimitiveType<T>) theContext.getElementDefinition(theType).newInstance();
092                primitive.setValue(theValue);
093                return primitive;
094        }
095
096        /**
097         * This is internal API- Use with caution as it may change
098         */
099        static BaseRuntimeChildDefinition getChild(FhirContext theContext, IBase theElement, String theName) {
100                BaseRuntimeElementCompositeDefinition<?> def = (BaseRuntimeElementCompositeDefinition<?>) theContext.getElementDefinition(theElement.getClass());
101                return def.getChildByName(theName);
102        }
103}