
ca.uhn.fhir.context.BaseRuntimeElementDefinition Maven / Gradle / Ivy
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 java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBase;
public abstract class BaseRuntimeElementDefinition {
private static final Class VOID_CLASS = Void.class;
private Map, Constructor> myConstructors = Collections.synchronizedMap(new HashMap, Constructor>());
private List myExtensions = new ArrayList();
private List myExtensionsModifier = new ArrayList();
private List myExtensionsNonModifier = new ArrayList();
private final Class extends T> myImplementingClass;
private final String myName;
private final boolean myStandardType;
private Map myUrlToExtension = new HashMap();
public BaseRuntimeElementDefinition(String theName, Class extends T> theImplementingClass, boolean theStandardType) {
assert StringUtils.isNotBlank(theName);
assert theImplementingClass != null;
String name = theName;
// TODO: remove this and fix for the model
if (name.endsWith("Dt")) {
name = name.substring(0, name.length() - 2);
}
myName = name;
myStandardType = theStandardType;
myImplementingClass = theImplementingClass;
}
public void addExtension(RuntimeChildDeclaredExtensionDefinition theExtension) {
if (theExtension == null) {
throw new NullPointerException();
}
myExtensions.add(theExtension);
}
public abstract ChildTypeEnum getChildType();
@SuppressWarnings("unchecked")
private Constructor getConstructor(Object theArgument) {
Class extends Object> argumentType;
if (theArgument == null) {
argumentType = VOID_CLASS;
} else {
argumentType = theArgument.getClass();
}
Constructor retVal = myConstructors.get(argumentType);
if (retVal == null) {
for (Constructor> next : getImplementingClass().getConstructors()) {
if (argumentType == VOID_CLASS) {
if (next.getParameterTypes().length == 0) {
retVal = (Constructor) next;
break;
}
} else if (next.getParameterTypes().length == 1) {
if (next.getParameterTypes()[0].isAssignableFrom(argumentType)) {
retVal = (Constructor) next;
break;
}
}
}
if (retVal == null) {
throw new ConfigurationException("Class " + getImplementingClass() + " has no constructor with a single argument of type " + argumentType);
}
myConstructors.put(argumentType, retVal);
}
return retVal;
}
/**
* @return Returns null if none
*/
public RuntimeChildDeclaredExtensionDefinition getDeclaredExtension(String theExtensionUrl) {
validateSealed();
return myUrlToExtension.get(theExtensionUrl);
}
public List getExtensions() {
validateSealed();
return myExtensions;
}
public List getExtensionsModifier() {
validateSealed();
return myExtensionsModifier;
}
public List getExtensionsNonModifier() {
validateSealed();
return myExtensionsNonModifier;
}
public Class extends T> getImplementingClass() {
return myImplementingClass;
}
/**
* @return Returns the runtime name for this resource (i.e. the name that
* will be used in encoded messages)
*/
public String getName() {
return myName;
}
public boolean isStandardType() {
return myStandardType;
}
public T newInstance() {
return newInstance(null);
}
public T newInstance(Object theArgument) {
try {
if (theArgument == null) {
return getConstructor(null).newInstance(null);
} else {
return getConstructor(theArgument).newInstance(theArgument);
}
} catch (Exception e) {
throw new ConfigurationException("Failed to instantiate type:" + getImplementingClass().getName(), e);
}
}
/**
* Invoked prior to use to perform any initialization and make object
* mutable.
* @param theContext TODO
*/
void sealAndInitialize(FhirContext theContext, Map, BaseRuntimeElementDefinition>> theClassToElementDefinitions) {
for (BaseRuntimeChildDefinition next : myExtensions) {
next.sealAndInitialize(theContext, theClassToElementDefinitions);
}
for (RuntimeChildDeclaredExtensionDefinition next : myExtensions) {
String extUrl = next.getExtensionUrl();
if (myUrlToExtension.containsKey(extUrl)) {
throw new ConfigurationException("Duplicate extension URL[" + extUrl + "] in Element[" + getName() + "]");
} else {
myUrlToExtension.put(extUrl, next);
}
if (next.isModifier()) {
myExtensionsModifier.add(next);
} else {
myExtensionsNonModifier.add(next);
}
}
myExtensions = Collections.unmodifiableList(myExtensions);
}
@Override
public String toString() {
return getClass().getSimpleName()+"[" + getName() + ", " + getImplementingClass().getSimpleName() + "]";
}
protected void validateSealed() {
/*
* this does nothing, but BaseRuntimeElementCompositeDefinition
* overrides this method to provide functionality because that class
* defers the dealing process
*/
}
public enum ChildTypeEnum {
COMPOSITE_DATATYPE, /**
* HL7.org structure style.
*/
CONTAINED_RESOURCE_LIST, /**
* HAPI structure style.
*/
CONTAINED_RESOURCES, EXTENSION_DECLARED,
ID_DATATYPE,
PRIMITIVE_DATATYPE, /**
* HAPI style.
*/
PRIMITIVE_XHTML,
/**
* HL7.org style.
*/
PRIMITIVE_XHTML_HL7ORG,
RESOURCE,
RESOURCE_BLOCK,
UNDECL_EXT,
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy