All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition Maven / Gradle / Ivy

There is a newer version: 7.6.1
Show newest version
package ca.uhn.fhir.context;

/*
 * #%L
 * HAPI FHIR - Core Library
 * %%
 * Copyright (C) 2014 - 2016 University Health Network
 * %%
 * 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.
 * #L%
 */
import static org.apache.commons.lang3.StringUtils.isNotBlank;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;

import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.Extension;

public class RuntimeChildDeclaredExtensionDefinition extends BaseRuntimeDeclaredChildDefinition {

	private BaseRuntimeElementDefinition myChildDef;
	private Class myChildType;
	private String myDatatypeChildName;
	private boolean myDefinedLocally;
	private String myExtensionUrl;
	private boolean myModifier;
	private Map myUrlToChildExtension;
	private volatile Object myInstanceConstructorArguments;
	private Class myEnumerationType;

	/**
	 * @param theBoundTypeBinder
	 *            If the child is of a type that requires a constructor argument to instantiate, this is the argument to
	 *            use
	 * @param theDefinedLocally
	 *            See {@link Extension#definedLocally()}
	 */
	RuntimeChildDeclaredExtensionDefinition(Field theField, Child theChild, Description theDescriptionAnnotation, Extension theExtension, String theElementName, String theExtensionUrl, Class theChildType, Object theBoundTypeBinder)
			throws ConfigurationException {
		super(theField, theChild, theDescriptionAnnotation, theElementName);
		assert isNotBlank(theExtensionUrl);
		myExtensionUrl = theExtensionUrl;
		myChildType = theChildType;
		myDefinedLocally = theExtension.definedLocally();
		myModifier = theExtension.isModifier();
		myInstanceConstructorArguments = theBoundTypeBinder;
	}

	@Override
	public Object getInstanceConstructorArguments() {
		Object retVal = myInstanceConstructorArguments;
		if (retVal == null && myEnumerationType != null) {
			retVal = RuntimeChildPrimitiveEnumerationDatatypeDefinition.toEnumFactory(myEnumerationType);
			myInstanceConstructorArguments = retVal;
		}
		return retVal;
	}

	public void setEnumerationType(Class theEnumerationType) {
		myEnumerationType = theEnumerationType;
	}

	@Override
	public BaseRuntimeElementDefinition getChildByName(String theName) {
		if (myDatatypeChildName != null) {
			if (myDatatypeChildName.equals(theName)) {
				return myChildDef;
			} else {
				return null;
			}
		} else {
			return null;
		}
	}

	@Override
	public BaseRuntimeElementDefinition getChildElementDefinitionByDatatype(Class theType) {
		if (myChildType.equals(theType)) {
			return myChildDef;
		}
		return null;
	}

	public RuntimeChildDeclaredExtensionDefinition getChildExtensionForUrl(String theUrl) {
		return myUrlToChildExtension.get(theUrl);
	}

	@Override
	public String getChildNameByDatatype(Class theDatatype) {
		if (myChildType.equals(theDatatype) && myDatatypeChildName != null) {
			return myDatatypeChildName;
		} else {
			return "extension";
		}
	}

	public Class getChildType() {
		return myChildType;
	}

	@Override
	public String getExtensionUrl() {
		return myExtensionUrl;
	}

	@Override
	public BaseRuntimeElementDefinition getSingleChildOrThrow() {
		return myChildDef;
	}

	@Override
	public Set getValidChildNames() {
		return Collections.emptySet();
	}

	public boolean isDefinedLocally() {
		return myDefinedLocally;
	}

	@Override
	public boolean isModifier() {
		return myModifier;
	}

	public IBase newInstance() {
		try {
			return myChildType.newInstance();
		} catch (InstantiationException e) {
			throw new ConfigurationException("Failed to instantiate type:" + myChildType.getName(), e);
		} catch (IllegalAccessException e) {
			throw new ConfigurationException("Failed to instantiate type:" + myChildType.getName(), e);
		}
	}

	@Override
	void sealAndInitialize(FhirContext theContext, Map, BaseRuntimeElementDefinition> theClassToElementDefinitions) {
		myUrlToChildExtension = new HashMap();
		
		BaseRuntimeElementDefinition elementDef = theClassToElementDefinitions.get(myChildType);
		
		/*
		 * This will happen for any type that isn't defined in the base set of 
		 * built-in types, e.g. custom structures or custom extensions
		 */
		if (elementDef == null) {
			elementDef = theContext.getElementDefinition(myChildType);
		}
		
		if (elementDef instanceof RuntimePrimitiveDatatypeDefinition || elementDef instanceof RuntimeCompositeDatatypeDefinition) {
			myDatatypeChildName = "value" + elementDef.getName().substring(0, 1).toUpperCase() + elementDef.getName().substring(1);
			if ("valueResourceReference".equals(myDatatypeChildName)) {
				// Per one of the examples here: http://hl7.org/implement/standards/fhir/extensibility.html#extension
				myDatatypeChildName = "valueResource";
				List> types = new ArrayList>();
				types.add(IResource.class);
				myChildDef = findResourceReferenceDefinition(theClassToElementDefinitions);
			} else {
				myChildDef = elementDef;
			}
		} else {
			RuntimeResourceBlockDefinition extDef = ((RuntimeResourceBlockDefinition) elementDef);
			for (RuntimeChildDeclaredExtensionDefinition next : extDef.getExtensions()) {
				myUrlToChildExtension.put(next.getExtensionUrl(), next);
			}
			myChildDef = extDef;
		}

		myUrlToChildExtension = Collections.unmodifiableMap(myUrlToChildExtension);
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy