Start adding view generator

This commit is contained in:
James Agnew 2014-08-13 18:16:34 -04:00
parent 04b4d5acb7
commit 901ce12e8e
7 changed files with 141 additions and 21 deletions

View File

@ -62,6 +62,11 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IComposite
return retVal; return retVal;
} }
public BaseRuntimeChildDefinition getChildByName(String theName){
BaseRuntimeChildDefinition retVal = myNameToChild.get(theName);
return retVal;
}
public List<BaseRuntimeChildDefinition> getChildren() { public List<BaseRuntimeChildDefinition> getChildren() {
return myChildren; return myChildren;
} }

View File

@ -36,7 +36,13 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
Validate.notEmpty(theUrl, "URL must be populated"); Validate.notEmpty(theUrl, "URL must be populated");
Validate.notNull(theValue, "Value must not be null"); Validate.notNull(theValue, "Value must not be null");
ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl, theValue); ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl, theValue);
getUndeclaredExtensions().add(retVal); if (theIsModifier) {
getUndeclaredModifierExtensions();
myUndeclaredModifierExtensions.add(retVal);
} else {
getUndeclaredExtensions();
myUndeclaredExtensions.add(retVal);
}
return retVal; return retVal;
} }
@ -45,7 +51,13 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
Validate.notEmpty(theUrl, "URL must be populated"); Validate.notEmpty(theUrl, "URL must be populated");
ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl); ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl);
getUndeclaredExtensions().add(retVal); if (theIsModifier) {
getUndeclaredModifierExtensions();
myUndeclaredModifierExtensions.add(retVal);
} else {
getUndeclaredExtensions();
myUndeclaredExtensions.add(retVal);
}
return retVal; return retVal;
} }
@ -53,9 +65,11 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
public void addUndeclaredExtension(ExtensionDt theExtension) { public void addUndeclaredExtension(ExtensionDt theExtension) {
Validate.notNull(theExtension, "Extension can not be null"); Validate.notNull(theExtension, "Extension can not be null");
if (theExtension.isModifier()) { if (theExtension.isModifier()) {
getUndeclaredModifierExtensions().add(theExtension); getUndeclaredModifierExtensions();
myUndeclaredModifierExtensions.add(theExtension);
} else { } else {
getUndeclaredExtensions().add(theExtension); getUndeclaredExtensions();
myUndeclaredExtensions.add(theExtension);
} }
} }
@ -76,7 +90,7 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
if (myUndeclaredExtensions == null) { if (myUndeclaredExtensions == null) {
myUndeclaredExtensions = new ArrayList<ExtensionDt>(); myUndeclaredExtensions = new ArrayList<ExtensionDt>();
} }
return myUndeclaredExtensions; return Collections.unmodifiableList(myUndeclaredExtensions);
} }
@Override @Override
@ -96,12 +110,12 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
if (myUndeclaredModifierExtensions == null) { if (myUndeclaredModifierExtensions == null) {
myUndeclaredModifierExtensions = new ArrayList<ExtensionDt>(); myUndeclaredModifierExtensions = new ArrayList<ExtensionDt>();
} }
return myUndeclaredModifierExtensions; return Collections.unmodifiableList(myUndeclaredModifierExtensions);
} }
/** /**
* Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all * Intended to be called by extending classes {@link #isEmpty()} implementations, returns <code>true</code> if all content in this superclass instance is empty per the semantics of
* content in this superclass instance is empty per the semantics of {@link #isEmpty()}. * {@link #isEmpty()}.
*/ */
protected boolean isBaseEmpty() { protected boolean isBaseEmpty() {
if (myUndeclaredExtensions != null) { if (myUndeclaredExtensions != null) {

View File

@ -42,10 +42,17 @@ public @interface Child {
int ORDER_UNKNOWN = -1; int ORDER_UNKNOWN = -1;
/** /**
* COnstant value to supply for {@link #max()} to indicate '*' (no maximum) * Constant value to supply for {@link #max()} to indicate '*' (no maximum)
*/ */
int MAX_UNLIMITED = -1; int MAX_UNLIMITED = -1;
/**
* Constant value to supply for {@link #order()} to indicate that this child should replace the
* entry in the superclass with the same name. This may be used to indicate to parsers that
*
*/
int REPLACE_PARENT = -2;
/** /**
* The name of this field, as it will appear in serialized versions of the message * The name of this field, as it will appear in serialized versions of the message
*/ */

View File

@ -0,0 +1,86 @@
package ca.uhn.fhir.model.view;
import java.util.List;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.BaseElement;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
public class ViewGenerator {
public <T extends IResource> T newView(FhirContext theContext, IResource theResource, Class<T> theTargetType) {
Class<? extends IResource> sourceType = theResource.getClass();
RuntimeResourceDefinition sourceDef = theContext.getResourceDefinition(theResource);
RuntimeResourceDefinition targetDef = theContext.getResourceDefinition(theTargetType);
if (sourceType.equals(theTargetType)) {
@SuppressWarnings("unchecked")
T resource = (T) theResource;
return resource;
}
T retVal;
try {
retVal = theTargetType.newInstance();
} catch (InstantiationException e) {
throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to instantiate " + theTargetType, e);
}
copyChildren(sourceDef, (BaseElement) theResource, targetDef, (BaseElement) retVal);
return retVal;
}
private void copyChildren(BaseRuntimeElementCompositeDefinition<?> theSourceDef, BaseElement theSource, BaseRuntimeElementCompositeDefinition<?> theTargetDef, BaseElement theTarget) {
if (!theSource.isEmpty()) {
List<BaseRuntimeChildDefinition> targetChildren = theTargetDef.getChildren();
for (BaseRuntimeChildDefinition nextChild : targetChildren) {
BaseRuntimeChildDefinition sourceChildEquivalent = theSourceDef.getChildByNameOrThrowDataFormatException(nextChild.getElementName());
if (sourceChildEquivalent == null) {
continue;
}
List<? extends IElement> sourceValues = sourceChildEquivalent.getAccessor().getValues(theTarget);
for (IElement nextElement : sourceValues) {
nextChild.getMutator().addValue(theTargetDef, nextElement);
}
}
List<RuntimeChildDeclaredExtensionDefinition> targetExts = theTargetDef.getExtensions();
for (RuntimeChildDeclaredExtensionDefinition nextExt : targetExts) {
String url = nextExt.getExtensionUrl();
RuntimeChildDeclaredExtensionDefinition sourceDeclaredExt = theSourceDef.getDeclaredExtension(url);
if (sourceDeclaredExt == null) {
for (ExtensionDt next : theSource.getAllUndeclaredExtensions()) {
if (next.getUrlAsString().equals(url)) {
nextExt.getMutator().addValue(theTarget, next.getValue());
}
}
} else {
List<? extends IElement> values = sourceDeclaredExt.getAccessor().getValues(theSource);
for (IElement nextElement : values) {
nextExt.getMutator().addValue(theTarget, nextElement);
}
}
}
}
}
}

View File

@ -109,17 +109,6 @@ public class JsonParser extends BaseParser implements IParser {
myContext = theContext; myContext = theContext;
} }
private void addToHeldExtensions(int valueIdx, ArrayList<ArrayList<HeldExtension>> list, RuntimeChildDeclaredExtensionDefinition theDef, IElement theValue) {
list.ensureCapacity(valueIdx);
while (list.size() <= valueIdx) {
list.add(null);
}
if (list.get(valueIdx) == null) {
list.set(valueIdx, new ArrayList<JsonParser.HeldExtension>());
}
list.get(valueIdx).add(new HeldExtension(theDef, theValue));
}
private void addToHeldExtensions(int valueIdx, List<ExtensionDt> ext, ArrayList<ArrayList<HeldExtension>> list) { private void addToHeldExtensions(int valueIdx, List<ExtensionDt> ext, ArrayList<ArrayList<HeldExtension>> list) {
if (ext.size() > 0) { if (ext.size() > 0) {
list.ensureCapacity(valueIdx); list.ensureCapacity(valueIdx);

View File

@ -0,0 +1,9 @@
package ca.uhn.fhir.parser;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu.resource.Organization;
@ResourceDef(name="Organization")
public class MyOrganization extends Organization {
}

View File

@ -7,6 +7,7 @@ import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.Extension; import ca.uhn.fhir.model.api.annotation.Extension;
import ca.uhn.fhir.model.api.annotation.ResourceDef; import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Patient; import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -24,6 +25,15 @@ public class MyPatient extends Patient {
@Description(shortDefinition="Some dates of note for the patient") @Description(shortDefinition="Some dates of note for the patient")
private List<DateTimeDt> myImportantDates; private List<DateTimeDt> myImportantDates;
@Child(name="managingOrganization", order=Child.REPLACE_PARENT, min=0, max=1, type={
ca.uhn.fhir.model.dstu.resource.Organization.class })
@Description(
shortDefinition="Organization that is the custodian of the patient record",
formalDefinition="Organization that is the custodian of the patient record"
)
private ResourceReferenceDt myManagingOrganization;
@Override @Override
public boolean isEmpty() { public boolean isEmpty() {
return super.isEmpty() && myPetName.isEmpty(); return super.isEmpty() && myPetName.isEmpty();