2014-02-18 08:26:49 -05:00
package ca.uhn.fhir.parser ;
2014-04-24 12:25:47 -04:00
/ *
* # % L
2014-07-21 09:24:38 -04:00
* HAPI FHIR - Core Library
2014-04-24 12:25:47 -04:00
* % %
2019-01-04 16:22:15 -05:00
* Copyright ( C ) 2014 - 2019 University Health Network
2014-04-24 12:25:47 -04:00
* % %
* 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
2019-07-05 11:19:51 -04:00
*
2016-08-25 07:32:37 -04:00
* http : //www.apache.org/licenses/LICENSE-2.0
2019-07-05 11:19:51 -04:00
*
2014-04-24 12:25:47 -04:00
* 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 %
* /
2016-11-21 14:48:44 +01:00
import ca.uhn.fhir.context.* ;
2015-02-16 11:33:46 -05:00
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IMutator ;
2016-11-21 14:48:44 +01:00
import ca.uhn.fhir.model.api.* ;
2016-12-19 14:03:11 -05:00
import ca.uhn.fhir.model.api.annotation.Child ;
2015-02-13 14:17:44 -05:00
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt ;
2014-12-01 08:13:32 -05:00
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap ;
2019-09-30 20:14:36 -04:00
import ca.uhn.fhir.model.primitive.IdDt ;
import ca.uhn.fhir.model.primitive.InstantDt ;
import ca.uhn.fhir.model.primitive.XhtmlDt ;
2017-05-15 18:06:55 -04:00
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType ;
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType ;
2017-08-13 14:39:47 -04:00
import ca.uhn.fhir.util.* ;
2019-09-30 20:14:36 -04:00
import org.apache.commons.lang3.StringUtils ;
import org.apache.commons.lang3.Validate ;
import org.apache.commons.lang3.tuple.Pair ;
import org.hl7.fhir.instance.model.api.* ;
import javax.xml.stream.events.StartElement ;
import javax.xml.stream.events.XMLEvent ;
import java.util.* ;
import static org.apache.commons.lang3.StringUtils.* ;
2014-02-18 08:26:49 -05:00
2014-05-07 08:18:43 -04:00
class ParserState < T > {
2014-02-18 08:26:49 -05:00
2014-02-21 21:06:11 -05:00
private static final org . slf4j . Logger ourLog = org . slf4j . LoggerFactory . getLogger ( ParserState . class ) ;
2016-03-24 11:09:41 +01:00
private final FhirContext myContext ;
private final IParserErrorHandler myErrorHandler ;
private final boolean myJsonMode ;
private final IParser myParser ;
2019-09-30 20:14:36 -04:00
private List < String > myComments = new ArrayList < String > ( 2 ) ;
private T myObject ;
2016-04-17 10:12:34 -04:00
private IBase myPreviousElement ;
private BaseState myState ;
2016-08-25 07:32:37 -04:00
2016-03-24 11:09:41 +01:00
private ParserState ( IParser theParser , FhirContext theContext , boolean theJsonMode , IParserErrorHandler theErrorHandler ) {
myParser = theParser ;
2014-02-21 21:06:11 -05:00
myContext = theContext ;
2014-03-22 12:33:07 -04:00
myJsonMode = theJsonMode ;
2015-05-26 21:03:49 -04:00
myErrorHandler = theErrorHandler ;
2014-02-21 21:06:11 -05:00
}
2014-02-19 17:33:46 -05:00
2014-02-27 16:51:43 -05:00
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
myState . attributeValue ( theName , theValue ) ;
2014-02-19 17:33:46 -05:00
}
2016-02-08 22:05:17 -05:00
public void commentPost ( String theCommentText ) {
if ( myPreviousElement ! = null ) {
myPreviousElement . getFormatCommentsPost ( ) . add ( theCommentText ) ;
}
}
public void commentPre ( String theCommentText ) {
if ( myState . getCurrentElement ( ) ! = null ) {
IBase element = myState . getCurrentElement ( ) ;
element . getFormatCommentsPre ( ) . add ( theCommentText ) ;
}
}
2016-12-19 14:03:11 -05:00
public boolean elementIsRepeating ( String theChildName ) {
return myState . elementIsRepeating ( theChildName ) ;
}
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
myState . endingElement ( ) ;
2014-02-21 21:06:11 -05:00
}
2014-02-19 11:59:12 -05:00
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theName ) throws DataFormatException {
myState . enteringNewElement ( theNamespaceUri , theName ) ;
2014-02-21 21:06:11 -05:00
}
2014-02-18 08:26:49 -05:00
2017-02-08 11:14:19 +01:00
public void enteringNewElementExtension ( StartElement theElem , String theUrlAttr , boolean theIsModifier , final String baseServerUrl ) {
myState . enteringNewElementExtension ( theElem , theUrlAttr , theIsModifier , baseServerUrl ) ;
2014-02-22 15:33:02 -05:00
}
2014-02-27 07:39:36 -05:00
public T getObject ( ) {
2016-04-23 13:54:16 -04:00
return myObject ;
2014-02-19 11:59:12 -05:00
}
2014-05-05 05:57:43 -07:00
public boolean isPreResource ( ) {
return myState . isPreResource ( ) ;
}
2015-02-16 11:33:46 -05:00
private Object newContainedDt ( IResource theTarget ) {
2016-05-26 21:42:03 -04:00
return ReflectionUtil . newInstance ( theTarget . getStructureFhirVersionEnum ( ) . getVersionImplementation ( ) . getContainedType ( ) ) ;
2015-02-14 13:27:11 -05:00
}
2016-04-23 13:54:16 -04:00
@SuppressWarnings ( " unchecked " )
2014-06-03 16:52:21 -04:00
private void pop ( ) {
2016-02-08 22:05:17 -05:00
myPreviousElement = myState . getCurrentElement ( ) ;
2016-04-23 13:54:16 -04:00
if ( myState . myStack ! = null ) {
myState = myState . myStack ;
myState . wereBack ( ) ;
} else {
myObject = ( T ) myState . getCurrentElement ( ) ;
myState = null ;
}
2014-06-03 16:52:21 -04:00
}
private void push ( BaseState theState ) {
theState . setStack ( myState ) ;
myState = theState ;
2016-02-08 22:05:17 -05:00
if ( myComments . isEmpty ( ) = = false ) {
if ( myState . getCurrentElement ( ) ! = null ) {
myState . getCurrentElement ( ) . getFormatCommentsPre ( ) . addAll ( myComments ) ;
myComments . clear ( ) ;
}
}
2014-06-03 16:52:21 -04:00
}
2015-02-14 13:27:11 -05:00
2017-08-13 14:39:47 -04:00
public void string ( String theData ) {
myState . string ( theData ) ;
}
2015-02-14 13:27:11 -05:00
2017-08-13 14:39:47 -04:00
public boolean verifyNamespace ( String theExpect , String theActual ) {
if ( myJsonMode ) {
return true ;
2015-02-14 13:27:11 -05:00
}
2017-08-13 14:39:47 -04:00
return StringUtils . equals ( theExpect , theActual ) ;
2015-02-14 13:27:11 -05:00
}
2017-08-13 14:39:47 -04:00
/ * *
* Invoked after any new XML event is individually processed , containing a copy of the XML event . This is basically
* intended for embedded XHTML content
* /
public void xmlEvent ( XMLEvent theNextEvent ) {
if ( myState ! = null ) {
myState . xmlEvent ( theNextEvent ) ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
}
2014-12-01 08:13:32 -05:00
2017-08-13 14:39:47 -04:00
private abstract class BaseState {
2015-02-08 19:21:29 -05:00
2017-08-13 14:39:47 -04:00
private PreResourceState myPreResourceState ;
private BaseState myStack ;
2015-02-08 19:21:29 -05:00
2017-08-13 14:39:47 -04:00
public BaseState ( PreResourceState thePreResourceState ) {
super ( ) ;
myPreResourceState = thePreResourceState ;
2015-02-08 19:21:29 -05:00
}
2017-08-13 14:39:47 -04:00
/ * *
2019-09-30 20:14:36 -04:00
* @param theValue The attribute value
2017-08-13 14:39:47 -04:00
* /
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
myErrorHandler . unknownAttribute ( null , theName ) ;
}
2014-12-01 08:13:32 -05:00
2017-08-13 14:39:47 -04:00
public boolean elementIsRepeating ( String theChildName ) {
return false ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
public void endingElement ( ) throws DataFormatException {
// ignore by default
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
/ * *
2019-09-30 20:14:36 -04:00
* @param theNamespaceUri The XML namespace ( if XML ) or null
2017-08-13 14:39:47 -04:00
* /
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
myErrorHandler . unknownElement ( null , theLocalPart ) ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
/ * *
* Default implementation just handles undeclared extensions
* /
@SuppressWarnings ( " unused " )
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier , final String baseServerUrl ) {
if ( myPreResourceState ! = null & & getCurrentElement ( ) instanceof ISupportsUndeclaredExtensions ) {
ExtensionDt newExtension = new ExtensionDt ( theIsModifier ) ;
newExtension . setUrl ( theUrlAttr ) ;
ISupportsUndeclaredExtensions elem = ( ISupportsUndeclaredExtensions ) getCurrentElement ( ) ;
elem . addUndeclaredExtension ( newExtension ) ;
ExtensionState newState = new ExtensionState ( myPreResourceState , newExtension ) ;
push ( newState ) ;
} else {
if ( theIsModifier = = false ) {
if ( getCurrentElement ( ) instanceof IBaseHasExtensions ) {
IBaseExtension < ? , ? > ext = ( ( IBaseHasExtensions ) getCurrentElement ( ) ) . addExtension ( ) ;
ext . setUrl ( theUrlAttr ) ;
ParserState < T > . ExtensionState newState = new ExtensionState ( myPreResourceState , ext ) ;
push ( newState ) ;
} else {
logAndSwallowUnexpectedElement ( " extension " ) ;
2014-12-01 08:13:32 -05:00
}
} else {
2017-08-13 14:39:47 -04:00
if ( getCurrentElement ( ) instanceof IBaseHasModifierExtensions ) {
IBaseExtension < ? , ? > ext = ( ( IBaseHasModifierExtensions ) getCurrentElement ( ) ) . addModifierExtension ( ) ;
ext . setUrl ( theUrlAttr ) ;
ParserState < T > . ExtensionState newState = new ExtensionState ( myPreResourceState , ext ) ;
push ( newState ) ;
} else {
logAndSwallowUnexpectedElement ( " modifierExtension " ) ;
2014-12-01 08:13:32 -05:00
}
}
}
}
2017-08-13 14:39:47 -04:00
protected IBase getCurrentElement ( ) {
return null ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
public PreResourceState getPreResourceState ( ) {
return myPreResourceState ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
public boolean isPreResource ( ) {
return false ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
protected void logAndSwallowUnexpectedElement ( String theLocalPart ) {
myErrorHandler . unknownElement ( null , theLocalPart ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
}
2014-12-01 08:13:32 -05:00
2017-08-13 14:39:47 -04:00
public void setStack ( BaseState theState ) {
myStack = theState ;
2014-12-01 08:13:32 -05:00
}
2017-08-13 14:39:47 -04:00
/ * *
2019-09-30 20:14:36 -04:00
* @param theData The string value
2017-08-13 14:39:47 -04:00
* /
public void string ( String theData ) {
// ignore by default
2014-12-01 08:13:32 -05:00
}
2015-02-14 13:27:11 -05:00
public void wereBack ( ) {
2017-08-13 14:39:47 -04:00
// allow an implementor to override
}
2015-02-14 13:27:11 -05:00
2017-08-13 14:39:47 -04:00
/ * *
2019-09-30 20:14:36 -04:00
* @param theNextEvent The XML event
2017-08-13 14:39:47 -04:00
* /
public void xmlEvent ( XMLEvent theNextEvent ) {
// ignore
2015-02-14 13:27:11 -05:00
}
2014-12-01 08:13:32 -05:00
}
2015-02-16 11:33:46 -05:00
private class ContainedResourcesStateHapi extends PreResourceState {
2014-03-22 12:33:07 -04:00
2015-02-16 11:33:46 -05:00
public ContainedResourcesStateHapi ( PreResourceState thePreResourcesState ) {
super ( thePreResourcesState , ( ( IResource ) thePreResourcesState . myInstance ) . getStructureFhirVersionEnum ( ) ) ;
2014-03-16 15:09:30 -04:00
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-03-16 15:09:30 -04:00
pop ( ) ;
}
2016-04-11 08:36:12 -04:00
@Override
protected void populateTarget ( ) {
// nothing
}
2014-03-16 15:09:30 -04:00
@Override
public void wereBack ( ) {
2016-04-01 17:10:49 -04:00
super . wereBack ( ) ;
2016-08-25 07:32:37 -04:00
2014-12-10 22:02:31 -05:00
IResource res = ( IResource ) getCurrentElement ( ) ;
2014-03-16 15:09:30 -04:00
assert res ! = null ;
2014-03-22 12:33:07 -04:00
if ( res . getId ( ) = = null | | res . getId ( ) . isEmpty ( ) ) {
2016-08-25 17:41:33 -04:00
// If there is no ID, we don't keep the resource because it's useless (contained resources
// need an ID to be referred to)
myErrorHandler . containedResourceWithNoId ( null ) ;
2014-03-16 15:09:30 -04:00
} else {
2014-10-15 14:34:14 -04:00
if ( ! res . getId ( ) . isLocal ( ) ) {
res . setId ( new IdDt ( '#' + res . getId ( ) . getIdPart ( ) ) ) ;
}
2016-08-05 18:01:44 -04:00
getPreResourceState ( ) . getContainedResources ( ) . put ( res . getId ( ) . getValueAsString ( ) , res ) ;
2014-03-16 15:09:30 -04:00
}
2014-12-10 22:02:31 -05:00
IResource preResCurrentElement = ( IResource ) getPreResourceState ( ) . getCurrentElement ( ) ;
2015-02-14 13:27:11 -05:00
2015-02-13 14:17:44 -05:00
@SuppressWarnings ( " unchecked " )
List < IResource > containedResources = ( List < IResource > ) preResCurrentElement . getContained ( ) . getContainedResources ( ) ;
containedResources . add ( res ) ;
2015-02-14 13:27:11 -05:00
2014-03-16 15:09:30 -04:00
}
}
2015-04-13 08:32:49 -04:00
private class ContainedResourcesStateHl7Org extends PreResourceState {
public ContainedResourcesStateHl7Org ( PreResourceState thePreResourcesState ) {
2015-12-13 22:44:41 -05:00
super ( thePreResourcesState , thePreResourcesState . myParentVersion ) ;
2015-04-13 08:32:49 -04:00
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
2016-04-11 08:36:12 -04:00
@Override
protected void populateTarget ( ) {
// nothing
}
2015-04-13 08:32:49 -04:00
@Override
public void wereBack ( ) {
2016-04-01 17:10:49 -04:00
super . wereBack ( ) ;
2015-04-13 08:32:49 -04:00
IBaseResource res = getCurrentElement ( ) ;
assert res ! = null ;
2015-05-05 18:16:22 -04:00
if ( res . getIdElement ( ) = = null | | res . getIdElement ( ) . isEmpty ( ) ) {
2016-08-25 17:41:33 -04:00
// If there is no ID, we don't keep the resource because it's useless (contained resources
// need an ID to be referred to)
myErrorHandler . containedResourceWithNoId ( null ) ;
2015-04-13 08:32:49 -04:00
} else {
2016-08-25 17:41:33 -04:00
res . getIdElement ( ) . setValue ( '#' + res . getIdElement ( ) . getIdPart ( ) ) ;
2016-08-05 18:01:44 -04:00
getPreResourceState ( ) . getContainedResources ( ) . put ( res . getIdElement ( ) . getValue ( ) , res ) ;
2015-04-13 08:32:49 -04:00
}
2015-04-21 13:30:58 -04:00
2015-04-13 08:32:49 -04:00
IBaseResource preResCurrentElement = getPreResourceState ( ) . getCurrentElement ( ) ;
RuntimeResourceDefinition def = myContext . getResourceDefinition ( preResCurrentElement ) ;
def . getChildByName ( " contained " ) . getMutator ( ) . addValue ( preResCurrentElement , res ) ;
}
}
2014-02-26 17:13:49 -05:00
private class DeclaredExtensionState extends BaseState {
2014-12-10 22:02:31 -05:00
private IBase myChildInstance ;
2014-02-26 17:13:49 -05:00
private RuntimeChildDeclaredExtensionDefinition myDefinition ;
2014-12-10 22:02:31 -05:00
private IBase myParentInstance ;
2014-03-16 15:09:30 -04:00
private PreResourceState myPreResourceState ;
2014-02-26 17:13:49 -05:00
2014-12-10 22:02:31 -05:00
public DeclaredExtensionState ( PreResourceState thePreResourceState , RuntimeChildDeclaredExtensionDefinition theDefinition , IBase theParentInstance ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourceState ) ;
2014-03-22 12:33:07 -04:00
myPreResourceState = thePreResourceState ;
2014-02-26 17:13:49 -05:00
myDefinition = theDefinition ;
myParentInstance = theParentInstance ;
}
2016-03-02 22:18:33 -05:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( theName . equals ( " url " ) ) {
// This can be ignored
return ;
}
super . attributeValue ( theName , theValue ) ;
}
2014-02-26 17:13:49 -05:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-02-26 17:13:49 -05:00
pop ( ) ;
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2014-02-26 17:13:49 -05:00
BaseRuntimeElementDefinition < ? > target = myDefinition . getChildByName ( theLocalPart ) ;
if ( target = = null ) {
2015-05-26 21:03:49 -04:00
myErrorHandler . unknownElement ( null , theLocalPart ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
2014-02-26 17:13:49 -05:00
}
switch ( target . getChildType ( ) ) {
2019-09-30 20:14:36 -04:00
case COMPOSITE_DATATYPE : {
BaseRuntimeElementCompositeDefinition < ? > compositeTarget = ( BaseRuntimeElementCompositeDefinition < ? > ) target ;
ICompositeType newChildInstance = ( ICompositeType ) compositeTarget . newInstance ( myDefinition . getInstanceConstructorArguments ( ) ) ;
myDefinition . getMutator ( ) . addValue ( myParentInstance , newChildInstance ) ;
ElementCompositeState newState = new ElementCompositeState ( myPreResourceState , theLocalPart , compositeTarget , newChildInstance ) ;
push ( newState ) ;
return ;
}
case ID_DATATYPE :
case PRIMITIVE_DATATYPE : {
RuntimePrimitiveDatatypeDefinition primitiveTarget = ( RuntimePrimitiveDatatypeDefinition ) target ;
IPrimitiveType < ? > newChildInstance = primitiveTarget . newInstance ( myDefinition . getInstanceConstructorArguments ( ) ) ;
myDefinition . getMutator ( ) . addValue ( myParentInstance , newChildInstance ) ;
PrimitiveState newState = new PrimitiveState ( getPreResourceState ( ) , newChildInstance ) ;
push ( newState ) ;
return ;
}
case PRIMITIVE_XHTML :
case RESOURCE :
case RESOURCE_BLOCK :
case UNDECL_EXT :
case EXTENSION_DECLARED :
default :
break ;
2014-02-26 17:13:49 -05:00
}
}
@Override
2017-02-08 11:14:19 +01:00
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier , final String baseServerUrl ) {
2014-02-26 17:13:49 -05:00
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition . getChildExtensionForUrl ( theUrlAttr ) ;
if ( declaredExtension ! = null ) {
if ( myChildInstance = = null ) {
myChildInstance = myDefinition . newInstance ( ) ;
myDefinition . getMutator ( ) . addValue ( myParentInstance , myChildInstance ) ;
}
2014-03-16 15:09:30 -04:00
BaseState newState = new DeclaredExtensionState ( getPreResourceState ( ) , declaredExtension , myChildInstance ) ;
2014-02-26 17:13:49 -05:00
push ( newState ) ;
} else {
2017-02-08 11:14:19 +01:00
super . enteringNewElementExtension ( theElement , theUrlAttr , theIsModifier , baseServerUrl ) ;
2014-02-26 17:13:49 -05:00
}
}
@Override
2014-12-10 22:02:31 -05:00
protected IBase getCurrentElement ( ) {
2014-02-26 17:13:49 -05:00
return myParentInstance ;
}
2014-02-20 12:13:05 -05:00
}
2014-02-19 11:59:12 -05:00
2015-03-11 09:11:36 -04:00
private class ElementCompositeState extends BaseState {
2014-02-19 11:59:12 -05:00
private BaseRuntimeElementCompositeDefinition < ? > myDefinition ;
2015-03-11 09:11:36 -04:00
private IBase myInstance ;
2015-07-21 08:28:40 -04:00
private Set < String > myParsedNonRepeatableNames = new HashSet < String > ( ) ;
2017-05-15 18:06:55 -04:00
private String myElementName ;
2014-02-18 08:26:49 -05:00
2017-05-15 18:06:55 -04:00
public ElementCompositeState ( PreResourceState thePreResourceState , String theElementName , BaseRuntimeElementCompositeDefinition < ? > theDef , IBase theInstance ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourceState ) ;
2014-02-19 11:59:12 -05:00
myDefinition = theDef ;
2014-02-18 08:26:49 -05:00
myInstance = theInstance ;
2017-05-15 18:06:55 -04:00
myElementName = theElementName ;
2014-02-18 08:26:49 -05:00
}
2014-03-16 15:09:30 -04:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( " id " . equals ( theName ) ) {
2014-07-04 09:27:36 -04:00
if ( myInstance instanceof IIdentifiableElement ) {
2014-08-19 07:48:06 -04:00
( ( IIdentifiableElement ) myInstance ) . setElementSpecificId ( ( theValue ) ) ;
2015-02-16 11:33:46 -05:00
} else if ( myInstance instanceof IBaseElement ) {
( ( IBaseElement ) myInstance ) . setId ( theValue ) ;
2014-12-10 17:40:47 -05:00
} else if ( myInstance instanceof IBaseResource ) {
2014-12-10 22:02:31 -05:00
new IdDt ( theValue ) . applyTo ( ( IBaseResource ) myInstance ) ;
2014-07-04 09:27:36 -04:00
}
2014-05-28 16:07:53 -04:00
} else if ( " url " . equals ( theName ) & & myInstance instanceof ExtensionDt ) {
2014-07-04 09:27:36 -04:00
( ( ExtensionDt ) myInstance ) . setUrl ( theValue ) ;
2015-09-07 10:08:11 -04:00
} else {
2017-05-15 18:06:55 -04:00
if ( myJsonMode ) {
myErrorHandler . incorrectJsonType ( null , myElementName , ValueType . OBJECT , null , ValueType . SCALAR , ScalarType . STRING ) ;
} else {
myErrorHandler . unknownAttribute ( null , theName ) ;
}
2014-03-16 15:09:30 -04:00
}
}
2016-12-19 14:03:11 -05:00
@Override
public boolean elementIsRepeating ( String theChildName ) {
2017-04-21 09:25:41 +02:00
BaseRuntimeChildDefinition child = myDefinition . getChildByName ( theChildName ) ;
if ( child = = null ) {
2016-12-19 14:03:11 -05:00
return false ;
}
2017-04-21 09:25:41 +02:00
return child . getMax ( ) > 1 | | child . getMax ( ) = = Child . MAX_UNLIMITED ;
2016-12-19 14:03:11 -05:00
}
2014-02-18 08:26:49 -05:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) {
2014-02-21 21:06:11 -05:00
pop ( ) ;
}
2017-08-13 14:39:47 -04:00
2014-02-21 21:06:11 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespace , String theChildName ) throws DataFormatException {
2017-04-21 09:25:41 +02:00
BaseRuntimeChildDefinition child = myDefinition . getChildByName ( theChildName ) ;
if ( child = = null ) {
2016-04-17 10:12:34 -04:00
if ( theChildName . equals ( " id " ) ) {
if ( getCurrentElement ( ) instanceof IIdentifiableElement ) {
push ( new IdentifiableElementIdState ( getPreResourceState ( ) , ( IIdentifiableElement ) getCurrentElement ( ) ) ) ;
return ;
}
}
2016-08-25 07:32:37 -04:00
2015-06-12 08:27:03 -04:00
/ *
2016-02-08 22:05:17 -05:00
* This means we ' ve found an element that doesn ' t exist on the structure . If the error handler doesn ' t throw
* an exception , swallow the element silently along with any child elements
2015-05-26 21:03:49 -04:00
* /
myErrorHandler . unknownElement ( null , theChildName ) ;
2014-03-28 17:11:56 -04:00
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
}
2015-08-06 10:50:36 -04:00
2015-07-21 09:45:53 -04:00
if ( ( child . getMax ( ) = = 0 | | child . getMax ( ) = = 1 ) & & ! myParsedNonRepeatableNames . add ( theChildName ) ) {
2015-07-21 08:28:40 -04:00
myErrorHandler . unexpectedRepeatingElement ( null , theChildName ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
}
2015-08-06 10:50:36 -04:00
2014-02-19 11:59:12 -05:00
BaseRuntimeElementDefinition < ? > target = child . getChildByName ( theChildName ) ;
2014-02-26 09:03:43 -05:00
if ( target = = null ) {
2015-05-26 21:03:49 -04:00
// This is a bug with the structures and shouldn't happen..
2014-02-26 09:03:43 -05:00
throw new DataFormatException ( " Found unexpected element ' " + theChildName + " ' in parent element ' " + myDefinition . getName ( ) + " '. Valid names are: " + child . getValidChildNames ( ) ) ;
}
2014-02-26 17:13:49 -05:00
2014-02-19 11:59:12 -05:00
switch ( target . getChildType ( ) ) {
2019-09-30 20:14:36 -04:00
case COMPOSITE_DATATYPE : {
BaseRuntimeElementCompositeDefinition < ? > compositeTarget = ( BaseRuntimeElementCompositeDefinition < ? > ) target ;
ICompositeType newChildInstance = ( ICompositeType ) compositeTarget . newInstance ( child . getInstanceConstructorArguments ( ) ) ;
child . getMutator ( ) . addValue ( myInstance , newChildInstance ) ;
ParserState < T > . ElementCompositeState newState = new ElementCompositeState ( getPreResourceState ( ) , theChildName , compositeTarget , newChildInstance ) ;
push ( newState ) ;
return ;
2014-03-22 12:33:07 -04:00
}
2019-09-30 20:14:36 -04:00
case ID_DATATYPE :
case PRIMITIVE_DATATYPE : {
RuntimePrimitiveDatatypeDefinition primitiveTarget = ( RuntimePrimitiveDatatypeDefinition ) target ;
IPrimitiveType < ? > newChildInstance ;
newChildInstance = primitiveTarget . newInstance ( child . getInstanceConstructorArguments ( ) ) ;
child . getMutator ( ) . addValue ( myInstance , newChildInstance ) ;
PrimitiveState newState = new PrimitiveState ( getPreResourceState ( ) , newChildInstance ) ;
push ( newState ) ;
return ;
}
case RESOURCE_BLOCK : {
RuntimeResourceBlockDefinition blockTarget = ( RuntimeResourceBlockDefinition ) target ;
IBase newBlockInstance = blockTarget . newInstance ( ) ;
child . getMutator ( ) . addValue ( myInstance , newBlockInstance ) ;
ElementCompositeState newState = new ElementCompositeState ( getPreResourceState ( ) , theChildName , blockTarget , newBlockInstance ) ;
push ( newState ) ;
return ;
}
case PRIMITIVE_XHTML : {
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = ( RuntimePrimitiveDatatypeNarrativeDefinition ) target ;
XhtmlDt newDt = xhtmlTarget . newInstance ( ) ;
child . getMutator ( ) . addValue ( myInstance , newDt ) ;
XhtmlState state = new XhtmlState ( getPreResourceState ( ) , newDt , true ) ;
2015-04-03 15:42:02 -04:00
push ( state ) ;
2019-09-30 20:14:36 -04:00
return ;
}
case PRIMITIVE_XHTML_HL7ORG : {
RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition xhtmlTarget = ( RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition ) target ;
IBaseXhtml newDt = xhtmlTarget . newInstance ( ) ;
child . getMutator ( ) . addValue ( myInstance , newDt ) ;
XhtmlStateHl7Org state = new XhtmlStateHl7Org ( getPreResourceState ( ) , newDt ) ;
2015-04-23 22:19:04 -04:00
push ( state ) ;
2019-09-30 20:14:36 -04:00
return ;
}
case CONTAINED_RESOURCES : {
List < ? extends IBase > values = child . getAccessor ( ) . getValues ( myInstance ) ;
Object newDt ;
if ( values = = null | | values . isEmpty ( ) | | values . get ( 0 ) = = null ) {
newDt = newContainedDt ( ( IResource ) getPreResourceState ( ) . myInstance ) ;
child . getMutator ( ) . addValue ( myInstance , ( IBase ) newDt ) ;
} else {
newDt = values . get ( 0 ) ;
}
ContainedResourcesStateHapi state = new ContainedResourcesStateHapi ( getPreResourceState ( ) ) ;
push ( state ) ;
return ;
}
case CONTAINED_RESOURCE_LIST : {
ContainedResourcesStateHl7Org state = new ContainedResourcesStateHl7Org ( getPreResourceState ( ) ) ;
push ( state ) ;
return ;
}
case RESOURCE : {
if ( myInstance instanceof IAnyResource | | myInstance instanceof IBaseBackboneElement | | myInstance instanceof IBaseElement ) {
ParserState < T > . PreResourceStateHl7Org state = new PreResourceStateHl7Org ( myInstance , child . getMutator ( ) , null ) ;
push ( state ) ;
} else {
ParserState < T > . PreResourceStateHapi state = new PreResourceStateHapi ( myInstance , child . getMutator ( ) , null ) ;
push ( state ) ;
}
return ;
}
case UNDECL_EXT :
case EXTENSION_DECLARED : {
// Throw an exception because this shouldn't happen here
break ;
2015-04-03 15:42:02 -04:00
}
2014-02-22 15:33:02 -05:00
}
throw new DataFormatException ( " Illegal resource position: " + target . getChildType ( ) ) ;
}
@Override
2017-02-08 11:14:19 +01:00
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier , final String baseServerUrl ) {
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition . getDeclaredExtension ( theUrlAttr , baseServerUrl ) ;
2014-02-26 17:13:49 -05:00
if ( declaredExtension ! = null ) {
2014-03-16 15:09:30 -04:00
BaseState newState = new DeclaredExtensionState ( getPreResourceState ( ) , declaredExtension , myInstance ) ;
2014-02-26 17:13:49 -05:00
push ( newState ) ;
} else {
2017-02-08 11:14:19 +01:00
super . enteringNewElementExtension ( theElement , theUrlAttr , theIsModifier , baseServerUrl ) ;
2014-02-26 17:13:49 -05:00
}
2014-02-22 15:33:02 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-22 15:33:02 -05:00
@Override
2015-03-11 09:11:36 -04:00
protected IBase getCurrentElement ( ) {
2014-02-22 15:33:02 -05:00
return myInstance ;
}
}
2016-04-17 10:12:34 -04:00
public class ElementIdState extends BaseState {
private IBaseElement myElement ;
public ElementIdState ( ParserState < T > . PreResourceState thePreResourceState , IBaseElement theElement ) {
super ( thePreResourceState ) ;
myElement = theElement ;
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
myElement . setId ( theValue ) ;
}
@Override
public void endingElement ( ) {
pop ( ) ;
}
}
2014-02-22 15:33:02 -05:00
private class ExtensionState extends BaseState {
2015-05-05 13:16:10 -04:00
private IBaseExtension < ? , ? > myExtension ;
2014-02-22 15:33:02 -05:00
2015-05-05 13:16:10 -04:00
public ExtensionState ( PreResourceState thePreResourceState , IBaseExtension < ? , ? > theExtension ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourceState ) ;
2014-02-22 15:33:02 -05:00
myExtension = theExtension ;
}
2015-06-18 09:00:56 -04:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( " url " . equals ( theName ) ) {
// The URL attribute is handles in the XML loop as a special case since it is "url" instead
// of "value" like every single other place
return ;
}
2016-04-17 10:12:34 -04:00
if ( " id " . equals ( theName ) ) {
if ( getCurrentElement ( ) instanceof IBaseElement ) {
2016-08-25 07:32:37 -04:00
( ( IBaseElement ) getCurrentElement ( ) ) . setId ( theValue ) ;
2016-04-17 10:12:34 -04:00
return ;
} else if ( getCurrentElement ( ) instanceof IIdentifiableElement ) {
2016-08-25 07:32:37 -04:00
( ( IIdentifiableElement ) getCurrentElement ( ) ) . setElementSpecificId ( theValue ) ;
2016-04-17 10:12:34 -04:00
return ;
}
}
2015-06-18 09:00:56 -04:00
super . attributeValue ( theName , theValue ) ;
}
2014-02-22 15:33:02 -05:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2015-02-20 17:34:13 -05:00
if ( myExtension . getValue ( ) ! = null & & myExtension . getExtension ( ) . size ( ) > 0 ) {
2015-07-07 17:27:10 -04:00
throw new DataFormatException ( " Extension (URL=' " + myExtension . getUrl ( ) + " ') must not have both a value and other contained extensions " ) ;
2014-02-18 18:10:50 -05:00
}
2014-02-22 15:33:02 -05:00
pop ( ) ;
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2016-04-17 10:12:34 -04:00
if ( theLocalPart . equals ( " id " ) ) {
if ( getCurrentElement ( ) instanceof IBaseElement ) {
2017-08-13 14:39:47 -04:00
push ( new ElementIdState ( getPreResourceState ( ) , ( IBaseElement ) getCurrentElement ( ) ) ) ;
2016-04-17 10:12:34 -04:00
return ;
} else if ( getCurrentElement ( ) instanceof IIdentifiableElement ) {
2017-08-13 14:39:47 -04:00
push ( new IdentifiableElementIdState ( getPreResourceState ( ) , ( IIdentifiableElement ) getCurrentElement ( ) ) ) ;
2016-04-17 10:12:34 -04:00
return ;
}
}
2017-08-13 14:39:47 -04:00
2014-02-22 15:33:02 -05:00
BaseRuntimeElementDefinition < ? > target = myContext . getRuntimeChildUndeclaredExtensionDefinition ( ) . getChildByName ( theLocalPart ) ;
2017-08-13 14:39:47 -04:00
2016-08-25 07:32:37 -04:00
if ( target ! = null ) {
switch ( target . getChildType ( ) ) {
2019-09-30 20:14:36 -04:00
case COMPOSITE_DATATYPE : {
BaseRuntimeElementCompositeDefinition < ? > compositeTarget = ( BaseRuntimeElementCompositeDefinition < ? > ) target ;
ICompositeType newChildInstance = ( ICompositeType ) compositeTarget . newInstance ( ) ;
myExtension . setValue ( newChildInstance ) ;
ElementCompositeState newState = new ElementCompositeState ( getPreResourceState ( ) , theLocalPart , compositeTarget , newChildInstance ) ;
push ( newState ) ;
return ;
}
case ID_DATATYPE :
case PRIMITIVE_DATATYPE : {
RuntimePrimitiveDatatypeDefinition primitiveTarget = ( RuntimePrimitiveDatatypeDefinition ) target ;
IPrimitiveType < ? > newChildInstance = primitiveTarget . newInstance ( ) ;
myExtension . setValue ( newChildInstance ) ;
PrimitiveState newState = new PrimitiveState ( getPreResourceState ( ) , newChildInstance ) ;
push ( newState ) ;
return ;
}
case CONTAINED_RESOURCES :
case CONTAINED_RESOURCE_LIST :
case EXTENSION_DECLARED :
case PRIMITIVE_XHTML :
case PRIMITIVE_XHTML_HL7ORG :
case RESOURCE :
case RESOURCE_BLOCK :
case UNDECL_EXT :
break ;
2016-08-25 07:32:37 -04:00
}
2014-02-21 21:06:11 -05:00
}
2016-08-25 07:32:37 -04:00
// We hit an invalid type for the extension
myErrorHandler . unknownElement ( null , theLocalPart ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
2014-02-22 15:33:02 -05:00
}
2017-08-13 14:39:47 -04:00
2014-02-26 17:13:49 -05:00
@Override
2015-05-05 13:16:10 -04:00
protected IBaseExtension < ? , ? > getCurrentElement ( ) {
2014-02-26 17:13:49 -05:00
return myExtension ;
}
}
2016-04-17 10:12:34 -04:00
public class IdentifiableElementIdState extends BaseState {
private IIdentifiableElement myElement ;
public IdentifiableElementIdState ( ParserState < T > . PreResourceState thePreResourceState , IIdentifiableElement theElement ) {
super ( thePreResourceState ) ;
myElement = theElement ;
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
myElement . setElementSpecificId ( theValue ) ;
}
@Override
public void endingElement ( ) {
pop ( ) ;
}
}
2014-12-01 08:13:32 -05:00
private class MetaElementState extends BaseState {
private ResourceMetadataMap myMap ;
2014-02-27 16:51:43 -05:00
2014-12-01 08:13:32 -05:00
public MetaElementState ( ParserState < T > . PreResourceState thePreResourceState , ResourceMetadataMap theMap ) {
super ( thePreResourceState ) ;
myMap = theMap ;
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2014-12-01 08:13:32 -05:00
if ( theLocalPart . equals ( " versionId " ) ) {
push ( new MetaVersionElementState ( getPreResourceState ( ) , myMap ) ) ;
2015-04-21 13:30:58 -04:00
// } else if (theLocalPart.equals("profile")) {
//
2014-12-01 08:13:32 -05:00
} else if ( theLocalPart . equals ( " lastUpdated " ) ) {
InstantDt updated = new InstantDt ( ) ;
push ( new PrimitiveState ( getPreResourceState ( ) , updated ) ) ;
myMap . put ( ResourceMetadataKeyEnum . UPDATED , updated ) ;
2015-02-19 18:14:02 -07:00
} else if ( theLocalPart . equals ( " security " ) ) {
2015-02-24 07:49:31 -05:00
@SuppressWarnings ( " unchecked " )
2015-12-13 22:44:41 -05:00
List < IBase > securityLabels = ( List < IBase > ) myMap . get ( ResourceMetadataKeyEnum . SECURITY_LABELS ) ;
2015-02-19 18:14:02 -07:00
if ( securityLabels = = null ) {
2018-02-24 10:57:32 -05:00
securityLabels = new ArrayList < > ( ) ;
2015-02-19 18:14:02 -07:00
myMap . put ( ResourceMetadataKeyEnum . SECURITY_LABELS , securityLabels ) ;
}
2015-12-13 22:44:41 -05:00
IBase securityLabel = myContext . getVersion ( ) . newCodingDt ( ) ;
2015-02-24 07:49:31 -05:00
BaseRuntimeElementCompositeDefinition < ? > codinfDef = ( BaseRuntimeElementCompositeDefinition < ? > ) myContext . getElementDefinition ( securityLabel . getClass ( ) ) ;
push ( new SecurityLabelElementStateHapi ( getPreResourceState ( ) , codinfDef , securityLabel ) ) ;
2015-02-19 18:14:02 -07:00
securityLabels . add ( securityLabel ) ;
2015-03-16 17:02:44 -04:00
} else if ( theLocalPart . equals ( " profile " ) ) {
@SuppressWarnings ( " unchecked " )
List < IdDt > profiles = ( List < IdDt > ) myMap . get ( ResourceMetadataKeyEnum . PROFILES ) ;
2016-09-16 21:02:22 +02:00
List < IdDt > newProfiles ;
if ( profiles ! = null ) {
newProfiles = new ArrayList < IdDt > ( profiles . size ( ) + 1 ) ;
newProfiles . addAll ( profiles ) ;
} else {
newProfiles = new ArrayList < IdDt > ( 1 ) ;
2015-03-16 17:02:44 -04:00
}
IdDt profile = new IdDt ( ) ;
push ( new PrimitiveState ( getPreResourceState ( ) , profile ) ) ;
2016-09-16 21:02:22 +02:00
newProfiles . add ( profile ) ;
myMap . put ( ResourceMetadataKeyEnum . PROFILES , Collections . unmodifiableList ( newProfiles ) ) ;
2015-03-16 17:02:44 -04:00
} else if ( theLocalPart . equals ( " tag " ) ) {
TagList tagList = ( TagList ) myMap . get ( ResourceMetadataKeyEnum . TAG_LIST ) ;
if ( tagList = = null ) {
tagList = new TagList ( ) ;
myMap . put ( ResourceMetadataKeyEnum . TAG_LIST , tagList ) ;
}
push ( new TagState ( tagList ) ) ;
2014-12-01 08:13:32 -05:00
} else {
2015-05-26 21:03:49 -04:00
myErrorHandler . unknownElement ( null , theLocalPart ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
2014-12-01 08:13:32 -05:00
}
}
2017-11-01 11:37:51 +01:00
@Override
public void enteringNewElementExtension ( StartElement theElem , String theUrlAttr , boolean theIsModifier , final String baseServerUrl ) {
ResourceMetadataKeyEnum . ExtensionResourceMetadataKey resourceMetadataKeyEnum = new ResourceMetadataKeyEnum . ExtensionResourceMetadataKey ( theUrlAttr ) ;
Object metadataValue = myMap . get ( resourceMetadataKeyEnum ) ;
ExtensionDt newExtension ;
if ( metadataValue = = null ) {
newExtension = new ExtensionDt ( theIsModifier ) ;
} else if ( metadataValue instanceof ExtensionDt ) {
newExtension = ( ExtensionDt ) metadataValue ;
} else {
throw new IllegalStateException ( " Expected ExtensionDt as custom resource metadata type, got: " + metadataValue . getClass ( ) . getSimpleName ( ) ) ;
}
newExtension . setUrl ( theUrlAttr ) ;
myMap . put ( resourceMetadataKeyEnum , newExtension ) ;
ExtensionState newState = new ExtensionState ( getPreResourceState ( ) , newExtension ) ;
push ( newState ) ;
}
2014-12-01 08:13:32 -05:00
}
private class MetaVersionElementState extends BaseState {
private ResourceMetadataMap myMap ;
public MetaVersionElementState ( ParserState < T > . PreResourceState thePreResourceState , ResourceMetadataMap theMap ) {
super ( thePreResourceState ) ;
myMap = theMap ;
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
myMap . put ( ResourceMetadataKeyEnum . VERSION , theValue ) ;
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2015-05-26 21:03:49 -04:00
myErrorHandler . unknownElement ( null , theLocalPart ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
2014-12-01 08:13:32 -05:00
}
}
2015-02-16 11:33:46 -05:00
private abstract class PreResourceState extends BaseState {
2014-02-27 16:51:43 -05:00
2016-04-11 08:36:12 -04:00
private Map < String , IBaseResource > myContainedResources ;
2015-02-16 11:33:46 -05:00
private IBaseResource myInstance ;
2015-02-14 13:27:11 -05:00
private FhirVersionEnum myParentVersion ;
2015-05-29 17:50:18 -04:00
private boolean myRequireResourceType = true ;
2016-02-08 22:05:17 -05:00
private Class < ? extends IBaseResource > myResourceType ;
2014-02-27 16:51:43 -05:00
2015-02-16 11:33:46 -05:00
public PreResourceState ( Class < ? extends IBaseResource > theResourceType ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-05-05 05:57:43 -07:00
myResourceType = theResourceType ;
2016-04-11 08:36:12 -04:00
myContainedResources = new HashMap < String , IBaseResource > ( ) ;
2015-02-14 13:27:11 -05:00
if ( theResourceType ! = null ) {
myParentVersion = myContext . getResourceDefinition ( theResourceType ) . getStructureVersion ( ) ;
} else {
myParentVersion = myContext . getVersion ( ) . getVersion ( ) ;
}
2014-03-16 15:09:30 -04:00
}
2015-02-14 13:27:11 -05:00
public PreResourceState ( PreResourceState thePreResourcesState , FhirVersionEnum theParentVersion ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourcesState ) ;
2015-02-14 13:27:11 -05:00
Validate . notNull ( theParentVersion ) ;
myParentVersion = theParentVersion ;
2016-04-11 08:36:12 -04:00
myContainedResources = thePreResourcesState . getContainedResources ( ) ;
2014-02-27 16:51:43 -05:00
}
2014-02-26 17:13:49 -05:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2016-04-23 13:54:16 -04:00
stitchBundleCrossReferences ( ) ;
2014-02-27 16:51:43 -05:00
pop ( ) ;
2014-02-26 17:13:49 -05:00
}
2014-07-04 09:27:36 -04:00
2014-02-26 17:13:49 -05:00
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2014-03-07 16:23:49 -05:00
BaseRuntimeElementDefinition < ? > definition ;
if ( myResourceType = = null ) {
2016-03-24 11:09:41 +01:00
definition = null ;
if ( myParser . getPreferTypes ( ) ! = null ) {
for ( Class < ? extends IBaseResource > next : myParser . getPreferTypes ( ) ) {
RuntimeResourceDefinition nextDef = myContext . getResourceDefinition ( next ) ;
if ( nextDef . getName ( ) . equals ( theLocalPart ) ) {
definition = nextDef ;
}
}
}
if ( definition = = null ) {
definition = myContext . getResourceDefinition ( myParentVersion , theLocalPart ) ;
}
2014-08-27 08:55:00 -04:00
if ( ( definition = = null ) ) {
2015-02-14 13:27:11 -05:00
throw new DataFormatException ( " Element ' " + theLocalPart + " ' is not a known resource type, expected a resource at this position " ) ;
2014-03-07 16:23:49 -05:00
}
} else {
definition = myContext . getResourceDefinition ( myResourceType ) ;
2015-06-24 12:26:40 -04:00
if ( ! StringUtils . equals ( theLocalPart , definition . getName ( ) ) ) {
2015-05-29 17:50:18 -04:00
if ( myRequireResourceType ) {
throw new DataFormatException ( myContext . getLocalizer ( ) . getMessage ( ParserState . class , " wrongResourceTypeFound " , definition . getName ( ) , theLocalPart ) ) ;
}
2014-06-23 09:04:48 -04:00
definition = myContext . getResourceDefinition ( theLocalPart ) ;
if ( ! ( definition instanceof RuntimeResourceDefinition ) ) {
throw new DataFormatException ( " Element ' " + theLocalPart + " ' is not a resource, expected a resource at this position " ) ;
}
2014-03-07 16:23:49 -05:00
}
2014-02-26 17:13:49 -05:00
}
RuntimeResourceDefinition def = ( RuntimeResourceDefinition ) definition ;
2016-04-25 07:19:31 -04:00
if ( ! definition . getName ( ) . equals ( theLocalPart ) & & definition . getName ( ) . equalsIgnoreCase ( theLocalPart ) ) {
throw new DataFormatException ( " Unknown resource type ' " + theLocalPart + " ': Resource names are case sensitive, found similar name: ' " + definition . getName ( ) + " ' " ) ;
}
2015-02-16 11:33:46 -05:00
myInstance = def . newInstance ( ) ;
2014-02-26 17:13:49 -05:00
2017-08-13 14:39:47 -04:00
if ( myInstance instanceof IResource ) {
2015-02-16 11:33:46 -05:00
push ( new ResourceStateHapi ( getRootPreResourceState ( ) , def , ( IResource ) myInstance ) ) ;
2014-05-28 07:30:40 -04:00
} else {
2015-02-16 11:33:46 -05:00
push ( new ResourceStateHl7Org ( getRootPreResourceState ( ) , def , myInstance ) ) ;
2014-05-28 07:30:40 -04:00
}
2014-03-16 15:09:30 -04:00
}
2017-08-13 14:39:47 -04:00
2014-12-10 17:40:47 -05:00
public Map < String , IBaseResource > getContainedResources ( ) {
2014-03-16 15:09:30 -04:00
return myContainedResources ;
}
2014-06-03 16:52:21 -04:00
@Override
2014-12-10 17:40:47 -05:00
protected IBaseResource getCurrentElement ( ) {
2014-06-03 16:52:21 -04:00
return myInstance ;
}
private PreResourceState getRootPreResourceState ( ) {
if ( getPreResourceState ( ) ! = null ) {
return getPreResourceState ( ) ;
}
2017-02-08 16:41:03 +01:00
return this ;
2014-06-03 16:52:21 -04:00
}
2014-05-05 05:57:43 -07:00
@Override
public boolean isPreResource ( ) {
return true ;
}
2016-04-11 08:36:12 -04:00
protected abstract void populateTarget ( ) ;
2016-04-23 13:54:16 -04:00
private void postProcess ( ) {
2016-03-22 11:46:08 +01:00
if ( myContext . hasDefaultTypeForProfile ( ) ) {
IBaseMetaType meta = myInstance . getMeta ( ) ;
Class < ? extends IBaseResource > wantedProfileType = null ;
String usedProfile = null ;
for ( IPrimitiveType < String > next : meta . getProfile ( ) ) {
if ( isNotBlank ( next . getValue ( ) ) ) {
wantedProfileType = myContext . getDefaultTypeForProfile ( next . getValue ( ) ) ;
if ( wantedProfileType ! = null ) {
usedProfile = next . getValue ( ) ;
break ;
}
}
}
2016-08-25 07:32:37 -04:00
2016-03-22 11:46:08 +01:00
if ( wantedProfileType ! = null & & ! wantedProfileType . equals ( myInstance . getClass ( ) ) ) {
if ( myResourceType = = null | | myResourceType . isAssignableFrom ( wantedProfileType ) ) {
2019-09-30 20:14:36 -04:00
ourLog . debug ( " Converting resource of type {} to type defined for profile \" {} \" : {} " , new Object [ ] { myInstance . getClass ( ) . getName ( ) , usedProfile , wantedProfileType } ) ;
2016-08-25 07:32:37 -04:00
2016-03-22 11:46:08 +01:00
/ *
* This isn ' t the most efficient thing really . . If we want a specific
* type we just re - parse into that type . The problem is that we don ' t know
* until we ' ve parsed the resource which type we want to use because the
* profile declarations are in the text of the resource itself .
2019-09-30 20:14:36 -04:00
*
2016-03-22 11:46:08 +01:00
* At some point it would be good to write code which can present a view
* of one type backed by another type and use that .
* /
IParser parser = myContext . newJsonParser ( ) ;
String asString = parser . encodeResourceToString ( myInstance ) ;
myInstance = parser . parseResource ( wantedProfileType , asString ) ;
}
}
}
2016-04-23 13:54:16 -04:00
2017-08-13 14:39:47 -04:00
populateTarget ( ) ;
2016-12-19 14:03:11 -05:00
}
2016-04-23 13:54:16 -04:00
private void stitchBundleCrossReferences ( ) {
2016-04-05 08:59:24 -04:00
final boolean bundle = " Bundle " . equals ( myContext . getResourceDefinition ( myInstance ) . getName ( ) ) ;
2015-04-03 15:42:02 -04:00
if ( bundle ) {
2016-08-25 07:32:37 -04:00
2017-01-24 10:47:24 -05:00
FhirTerser t = myContext . newTerser ( ) ;
2017-08-13 14:39:47 -04:00
2017-01-24 10:47:24 -05:00
Map < String , IBaseResource > idToResource = new HashMap < String , IBaseResource > ( ) ;
2017-08-13 14:39:47 -04:00
List < IBase > entries = t . getValues ( myInstance , " Bundle.entry " , IBase . class ) ;
for ( IBase nextEntry : entries ) {
IPrimitiveType < ? > fullUrl = t . getSingleValueOrNull ( nextEntry , " fullUrl " , IPrimitiveType . class ) ;
if ( fullUrl ! = null & & isNotBlank ( fullUrl . getValueAsString ( ) ) ) {
IBaseResource resource = t . getSingleValueOrNull ( nextEntry , " resource " , IBaseResource . class ) ;
if ( resource ! = null ) {
idToResource . put ( fullUrl . getValueAsString ( ) , resource ) ;
2017-01-24 10:47:24 -05:00
}
}
}
2017-08-13 14:39:47 -04:00
2015-04-03 15:42:02 -04:00
/ *
* Stitch together resource references
* /
2016-04-05 08:59:24 -04:00
List < IBaseResource > resources = t . getAllPopulatedChildElementsOfType ( myInstance , IBaseResource . class ) ;
for ( IBaseResource next : resources ) {
IIdType id = next . getIdElement ( ) ;
2015-04-03 15:42:02 -04:00
if ( id ! = null & & id . isEmpty ( ) = = false ) {
String resName = myContext . getResourceDefinition ( next ) . getName ( ) ;
2017-01-24 10:47:24 -05:00
IIdType idType = id . withResourceType ( resName ) . toUnqualifiedVersionless ( ) ;
idToResource . put ( idType . getValueAsString ( ) , next ) ;
2015-04-03 15:42:02 -04:00
}
}
2016-04-05 08:59:24 -04:00
for ( IBaseResource next : resources ) {
List < IBaseReference > refs = myContext . newTerser ( ) . getAllPopulatedChildElementsOfType ( next , IBaseReference . class ) ;
for ( IBaseReference nextRef : refs ) {
if ( nextRef . isEmpty ( ) = = false & & nextRef . getReferenceElement ( ) ! = null ) {
2017-01-24 10:47:24 -05:00
IIdType unqualifiedVersionless = nextRef . getReferenceElement ( ) . toUnqualifiedVersionless ( ) ;
IBaseResource target = idToResource . get ( unqualifiedVersionless . getValueAsString ( ) ) ;
2015-04-03 15:42:02 -04:00
if ( target ! = null ) {
nextRef . setResource ( target ) ;
}
}
}
}
2016-04-05 08:59:24 -04:00
/ *
* Set resource IDs based on Bundle . entry . request . url
* /
List < Pair < String , IBaseResource > > urlsAndResources = BundleUtil . getBundleEntryUrlsAndResources ( myContext , ( IBaseBundle ) myInstance ) ;
for ( Pair < String , IBaseResource > pair : urlsAndResources ) {
if ( pair . getRight ( ) ! = null & & isNotBlank ( pair . getLeft ( ) ) & & pair . getRight ( ) . getIdElement ( ) . isEmpty ( ) ) {
if ( pair . getLeft ( ) . startsWith ( " urn: " ) ) {
pair . getRight ( ) . setId ( pair . getLeft ( ) ) ;
}
}
}
2016-08-25 07:32:37 -04:00
2015-04-03 15:42:02 -04:00
}
2014-02-26 17:13:49 -05:00
}
2016-12-19 14:03:11 -05:00
protected void weaveContainedResources ( ) {
FhirTerser terser = myContext . newTerser ( ) ;
terser . visit ( myInstance , new IModelVisitor ( ) {
@Override
2017-08-13 14:39:47 -04:00
public void acceptElement ( IBaseResource theResource , IBase theElement , List < String > thePathToElement , BaseRuntimeChildDefinition theChildDefinition ,
2019-09-30 20:14:36 -04:00
BaseRuntimeElementDefinition < ? > theDefinition ) {
2016-12-19 14:03:11 -05:00
if ( theElement instanceof BaseResourceReferenceDt ) {
BaseResourceReferenceDt nextRef = ( BaseResourceReferenceDt ) theElement ;
String ref = nextRef . getReference ( ) . getValue ( ) ;
if ( isNotBlank ( ref ) ) {
if ( ref . startsWith ( " # " ) ) {
IResource target = ( IResource ) myContainedResources . get ( ref ) ;
if ( target ! = null ) {
ourLog . debug ( " Resource contains local ref {} in field {} " , ref , thePathToElement ) ;
nextRef . setResource ( target ) ;
} else {
myErrorHandler . unknownReference ( null , ref ) ;
}
}
}
} else if ( theElement instanceof IBaseReference ) {
IBaseReference nextRef = ( IBaseReference ) theElement ;
String ref = nextRef . getReferenceElement ( ) . getValue ( ) ;
if ( isNotBlank ( ref ) ) {
if ( ref . startsWith ( " # " ) ) {
IBaseResource target = myContainedResources . get ( ref ) ;
if ( target ! = null ) {
ourLog . debug ( " Resource contains local ref {} in field {} " , ref , thePathToElement ) ;
nextRef . setResource ( target ) ;
} else {
myErrorHandler . unknownReference ( null , ref ) ;
}
}
}
}
}
} ) ;
}
@Override
public void wereBack ( ) {
postProcess ( ) ;
}
2014-02-18 08:26:49 -05:00
}
2016-02-08 22:05:17 -05:00
private class PreResourceStateHapi extends PreResourceState {
private IMutator myMutator ;
2019-09-30 20:14:36 -04:00
private IBase myTarget ;
2016-02-08 22:05:17 -05:00
public PreResourceStateHapi ( Class < ? extends IBaseResource > theResourceType ) {
super ( theResourceType ) ;
2016-02-28 19:38:54 -05:00
assert theResourceType = = null | | IResource . class . isAssignableFrom ( theResourceType ) ;
2016-02-08 22:05:17 -05:00
}
2019-09-30 20:14:36 -04:00
public PreResourceStateHapi ( IBase theTarget , IMutator theMutator , Class < ? extends IBaseResource > theResourceType ) {
2016-02-08 22:05:17 -05:00
super ( theResourceType ) ;
myTarget = theTarget ;
myMutator = theMutator ;
2016-02-28 19:38:54 -05:00
assert theResourceType = = null | | IResource . class . isAssignableFrom ( theResourceType ) ;
2016-02-08 22:05:17 -05:00
}
2016-08-25 07:32:37 -04:00
// @Override
// public void enteringNewElement(String theNamespaceUri, String theLocalPart) throws DataFormatException {
// super.enteringNewElement(theNamespaceUri, theLocalPart);
// populateTarget();
// }
2016-03-22 11:46:08 +01:00
2016-02-08 22:05:17 -05:00
@Override
2016-03-22 11:46:08 +01:00
protected void populateTarget ( ) {
2016-08-25 17:41:33 -04:00
weaveContainedResources ( ) ;
2016-02-08 22:05:17 -05:00
if ( myMutator ! = null ) {
2016-03-22 11:46:08 +01:00
myMutator . setValue ( myTarget , getCurrentElement ( ) ) ;
2016-02-08 22:05:17 -05:00
}
}
@Override
public void wereBack ( ) {
super . wereBack ( ) ;
IResource nextResource = ( IResource ) getCurrentElement ( ) ;
String version = ResourceMetadataKeyEnum . VERSION . get ( nextResource ) ;
String resourceName = myContext . getResourceDefinition ( nextResource ) . getName ( ) ;
String bundleIdPart = nextResource . getId ( ) . getIdPart ( ) ;
if ( isNotBlank ( bundleIdPart ) ) {
2019-09-30 20:14:36 -04:00
// if (isNotBlank(entryBaseUrl)) {
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
// } else {
IdDt previousId = nextResource . getId ( ) ;
nextResource . setId ( new IdDt ( null , resourceName , bundleIdPart , version ) ) ;
// Copy extensions
if ( ! previousId . getAllUndeclaredExtensions ( ) . isEmpty ( ) ) {
for ( final ExtensionDt ext : previousId . getAllUndeclaredExtensions ( ) ) {
nextResource . getId ( ) . addUndeclaredExtension ( ext ) ;
}
}
// }
2016-02-08 22:05:17 -05:00
}
}
}
private class PreResourceStateHl7Org extends PreResourceState {
private IMutator myMutator ;
2019-09-30 20:14:36 -04:00
private IBase myTarget ;
2016-02-08 22:05:17 -05:00
public PreResourceStateHl7Org ( Class < ? extends IBaseResource > theResourceType ) {
super ( theResourceType ) ;
}
2019-09-30 20:14:36 -04:00
public PreResourceStateHl7Org ( IBase theTarget , IMutator theMutator , Class < ? extends IBaseResource > theResourceType ) {
2016-02-08 22:05:17 -05:00
super ( theResourceType ) ;
myMutator = theMutator ;
myTarget = theTarget ;
}
@Override
2016-03-22 11:46:08 +01:00
protected void populateTarget ( ) {
2016-08-25 17:41:33 -04:00
weaveContainedResources ( ) ;
2016-02-08 22:05:17 -05:00
if ( myMutator ! = null ) {
2016-03-22 11:46:08 +01:00
myMutator . setValue ( myTarget , getCurrentElement ( ) ) ;
2016-02-08 22:05:17 -05:00
}
}
@Override
public void wereBack ( ) {
super . wereBack ( ) ;
if ( getCurrentElement ( ) instanceof IDomainResource ) {
IDomainResource elem = ( IDomainResource ) getCurrentElement ( ) ;
String resourceName = myContext . getResourceDefinition ( elem ) . getName ( ) ;
String versionId = elem . getMeta ( ) . getVersionId ( ) ;
if ( StringUtils . isBlank ( elem . getIdElement ( ) . getIdPart ( ) ) ) {
// Resource has no ID
} else if ( StringUtils . isNotBlank ( versionId ) ) {
elem . getIdElement ( ) . setValue ( resourceName + " / " + elem . getIdElement ( ) . getIdPart ( ) + " /_history/ " + versionId ) ;
} else {
elem . getIdElement ( ) . setValue ( resourceName + " / " + elem . getIdElement ( ) . getIdPart ( ) ) ;
}
}
}
}
2014-05-07 08:18:43 -04:00
private class PreTagListState extends BaseState {
private TagList myTagList ;
public PreTagListState ( ) {
super ( null ) ;
myTagList = new TagList ( ) ;
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2014-05-07 08:18:43 -04:00
if ( ! TagList . ELEMENT_NAME_LC . equals ( theLocalPart . toLowerCase ( ) ) ) {
throw new DataFormatException ( " resourceType does not appear to be 'TagList', found: " + theLocalPart ) ;
}
push ( new TagListState ( myTagList ) ) ;
}
2014-06-03 16:52:21 -04:00
@Override
2015-02-20 17:34:13 -05:00
protected IBase getCurrentElement ( ) {
2014-06-03 16:52:21 -04:00
return myTagList ;
}
2014-05-07 08:18:43 -04:00
@Override
public boolean isPreResource ( ) {
return true ;
}
}
2014-02-19 11:59:12 -05:00
private class PrimitiveState extends BaseState {
2014-12-10 22:02:31 -05:00
private IPrimitiveType < ? > myInstance ;
2014-02-19 11:59:12 -05:00
2014-12-10 22:02:31 -05:00
public PrimitiveState ( PreResourceState thePreResourceState , IPrimitiveType < ? > theInstance ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourceState ) ;
2014-02-19 11:59:12 -05:00
myInstance = theInstance ;
}
@Override
2014-02-27 16:51:43 -05:00
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( " value " . equals ( theName ) ) {
2016-11-21 14:48:44 +01:00
if ( " " . equals ( theValue ) ) {
myErrorHandler . invalidValue ( null , theValue , " Attribute values must not be empty ( \" \" ) " ) ;
} else {
2016-12-06 10:32:23 +10:00
try {
myInstance . setValueAsString ( theValue ) ;
2018-09-29 13:48:35 -04:00
} catch ( DataFormatException | IllegalArgumentException e ) {
2016-12-06 10:32:23 +10:00
myErrorHandler . invalidValue ( null , theValue , e . getMessage ( ) ) ;
}
2016-11-21 14:48:44 +01:00
}
2014-03-22 12:33:07 -04:00
} else if ( " id " . equals ( theName ) ) {
2014-07-04 09:27:36 -04:00
if ( myInstance instanceof IIdentifiableElement ) {
( ( IIdentifiableElement ) myInstance ) . setElementSpecificId ( theValue ) ;
2015-02-16 11:33:46 -05:00
} else if ( myInstance instanceof IBaseElement ) {
( ( IBaseElement ) myInstance ) . setId ( theValue ) ;
2014-12-10 17:40:47 -05:00
} else if ( myInstance instanceof IBaseResource ) {
2015-05-05 13:16:10 -04:00
new IdDt ( theValue ) . applyTo ( ( org . hl7 . fhir . instance . model . api . IBaseResource ) myInstance ) ;
2015-05-26 21:03:49 -04:00
} else {
myErrorHandler . unknownAttribute ( null , theName ) ;
2014-07-04 09:27:36 -04:00
}
2015-05-26 21:03:49 -04:00
} else {
myErrorHandler . unknownAttribute ( null , theName ) ;
2014-02-27 16:51:43 -05:00
}
2014-02-19 11:59:12 -05:00
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) {
2014-02-21 21:06:11 -05:00
pop ( ) ;
2014-02-19 11:59:12 -05:00
}
2014-03-06 17:12:05 -05:00
// @Override
2014-03-16 15:09:30 -04:00
// public void enteringNewElementExtension(StartElement theElement,
// String theUrlAttr) {
2014-03-06 17:12:05 -05:00
// if (myInstance instanceof ISupportsUndeclaredExtensions) {
// UndeclaredExtension ext = new UndeclaredExtension(theUrlAttr);
2014-03-16 15:09:30 -04:00
// ((ISupportsUndeclaredExtensions)
// myInstance).getUndeclaredExtensions().add(ext);
2014-03-06 17:12:05 -05:00
// push(new ExtensionState(ext));
// }
// }
2014-02-28 13:27:35 -05:00
2014-02-19 11:59:12 -05:00
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2015-05-26 21:03:49 -04:00
myErrorHandler . unknownElement ( null , theLocalPart ) ;
2014-12-21 18:13:37 -05:00
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
2014-02-19 11:59:12 -05:00
}
2015-02-14 13:27:11 -05:00
2014-02-22 15:33:02 -05:00
@Override
2014-12-10 22:02:31 -05:00
protected IBase getCurrentElement ( ) {
2014-02-26 17:13:49 -05:00
return myInstance ;
2014-02-22 15:33:02 -05:00
}
2014-02-19 11:59:12 -05:00
}
2015-03-11 09:11:36 -04:00
private class ResourceStateHapi extends ElementCompositeState {
private IResource myInstance ;
2015-02-14 13:27:11 -05:00
2015-02-16 11:33:46 -05:00
public ResourceStateHapi ( PreResourceState thePreResourceState , BaseRuntimeElementCompositeDefinition < ? > theDef , IResource theInstance ) {
2017-05-15 18:06:55 -04:00
super ( thePreResourceState , theDef . getName ( ) , theDef , theInstance ) ;
2015-03-11 09:11:36 -04:00
myInstance = theInstance ;
2015-02-14 13:27:11 -05:00
}
@Override
public void enteringNewElement ( String theNamespace , String theChildName ) throws DataFormatException {
if ( " id " . equals ( theChildName ) ) {
2015-03-11 09:11:36 -04:00
push ( new PrimitiveState ( getPreResourceState ( ) , myInstance . getId ( ) ) ) ;
2015-02-14 13:27:11 -05:00
} else if ( " meta " . equals ( theChildName ) ) {
2015-03-11 09:11:36 -04:00
push ( new MetaElementState ( getPreResourceState ( ) , myInstance . getResourceMetadata ( ) ) ) ;
2015-02-14 13:27:11 -05:00
} else {
super . enteringNewElement ( theNamespace , theChildName ) ;
}
}
}
2015-03-11 09:11:36 -04:00
private class ResourceStateHl7Org extends ElementCompositeState {
2015-02-16 11:33:46 -05:00
public ResourceStateHl7Org ( PreResourceState thePreResourceState , BaseRuntimeElementCompositeDefinition < ? > theDef , IBaseResource theInstance ) {
2017-05-15 18:06:55 -04:00
super ( thePreResourceState , theDef . getName ( ) , theDef , theInstance ) ;
2015-02-16 11:33:46 -05:00
}
}
2016-02-08 22:05:17 -05:00
private class SecurityLabelElementStateHapi extends ElementCompositeState {
public SecurityLabelElementStateHapi ( ParserState < T > . PreResourceState thePreResourceState , BaseRuntimeElementCompositeDefinition < ? > theDef , IBase codingDt ) {
2017-05-15 18:06:55 -04:00
super ( thePreResourceState , theDef . getName ( ) , theDef , codingDt ) ;
2016-02-08 22:05:17 -05:00
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
}
2014-05-05 05:57:43 -07:00
private class SwallowChildrenWholeState extends BaseState {
private int myDepth ;
public SwallowChildrenWholeState ( PreResourceState thePreResourceState ) {
super ( thePreResourceState ) ;
}
2016-02-08 22:05:17 -05:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
// ignore
}
2014-05-05 05:57:43 -07:00
@Override
public void endingElement ( ) throws DataFormatException {
myDepth - - ;
if ( myDepth < 0 ) {
pop ( ) ;
}
}
2014-10-24 15:43:35 -04:00
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2014-10-24 15:43:35 -04:00
myDepth + + ;
}
2014-05-05 05:57:43 -07:00
@Override
2017-02-08 11:14:19 +01:00
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier , final String baseServerUrl ) {
2014-05-05 05:57:43 -07:00
myDepth + + ;
}
}
2014-05-07 08:18:43 -04:00
private class TagListState extends BaseState {
private TagList myTagList ;
public TagListState ( TagList theTagList ) {
super ( null ) ;
myTagList = theTagList ;
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2014-05-07 08:18:43 -04:00
if ( TagList . ATTR_CATEGORY . equals ( theLocalPart ) ) {
2014-09-30 11:57:15 -04:00
push ( new TagState ( myTagList ) ) ;
2014-05-07 08:18:43 -04:00
} else {
throw new DataFormatException ( " Unexpected element: " + theLocalPart ) ;
}
}
2016-02-08 22:05:17 -05:00
@Override
protected IBase getCurrentElement ( ) {
return myTagList ;
}
2014-05-07 08:18:43 -04:00
}
private class TagState extends BaseState {
private static final int LABEL = 2 ;
private static final int NONE = 0 ;
private static final int SCHEME = 3 ;
private static final int TERM = 1 ;
2015-02-14 13:27:11 -05:00
private String myLabel ;
private String myScheme ;
2014-05-07 08:18:43 -04:00
private int mySubState = 0 ;
2014-09-30 11:57:15 -04:00
private TagList myTagList ;
private String myTerm ;
2014-05-07 08:18:43 -04:00
2014-09-30 11:57:15 -04:00
public TagState ( TagList theTagList ) {
2014-05-07 08:18:43 -04:00
super ( null ) ;
2014-09-30 11:57:15 -04:00
myTagList = theTagList ;
2014-05-07 08:18:43 -04:00
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
String value = defaultIfBlank ( theValue , null ) ;
switch ( mySubState ) {
2019-09-30 20:14:36 -04:00
case TERM :
myTerm = ( value ) ;
break ;
case LABEL :
myLabel = ( value ) ;
break ;
case SCHEME :
myScheme = ( value ) ;
break ;
case NONE :
// This handles JSON encoding, which is a bit weird
enteringNewElement ( null , theName ) ;
attributeValue ( null , value ) ;
endingElement ( ) ;
break ;
2014-05-07 08:18:43 -04:00
}
}
@Override
public void endingElement ( ) throws DataFormatException {
if ( mySubState ! = NONE ) {
mySubState = NONE ;
} else {
2014-09-30 11:57:15 -04:00
if ( isNotEmpty ( myScheme ) | | isNotBlank ( myTerm ) | | isNotBlank ( myLabel ) ) {
myTagList . addTag ( myScheme , myTerm , myLabel ) ;
}
2014-05-07 08:18:43 -04:00
pop ( ) ;
}
}
@Override
2015-06-24 12:26:40 -04:00
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
2015-03-16 17:02:44 -04:00
/ *
* We allow for both the DSTU1 and DSTU2 names here
* /
if ( Tag . ATTR_TERM . equals ( theLocalPart ) | | " code " . equals ( theLocalPart ) ) {
2014-05-07 08:18:43 -04:00
mySubState = TERM ;
2015-03-16 17:02:44 -04:00
} else if ( Tag . ATTR_SCHEME . equals ( theLocalPart ) | | " system " . equals ( theLocalPart ) ) {
2014-05-07 08:18:43 -04:00
mySubState = SCHEME ;
2015-03-16 17:02:44 -04:00
} else if ( Tag . ATTR_LABEL . equals ( theLocalPart ) | | " display " . equals ( theLocalPart ) ) {
2014-05-07 08:18:43 -04:00
mySubState = LABEL ;
} else {
throw new DataFormatException ( " Unexpected element: " + theLocalPart ) ;
}
}
}
2014-02-21 21:06:11 -05:00
private class XhtmlState extends BaseState {
2014-02-22 15:33:02 -05:00
private int myDepth ;
private XhtmlDt myDt ;
private List < XMLEvent > myEvents = new ArrayList < XMLEvent > ( ) ;
2014-02-27 16:51:43 -05:00
private boolean myIncludeOuterEvent ;
2014-02-22 15:33:02 -05:00
2014-03-16 15:09:30 -04:00
private XhtmlState ( PreResourceState thePreResourceState , XhtmlDt theXhtmlDt , boolean theIncludeOuterEvent ) throws DataFormatException {
super ( thePreResourceState ) ;
2014-02-27 16:51:43 -05:00
myDepth = 0 ;
2014-02-22 15:33:02 -05:00
myDt = theXhtmlDt ;
2014-02-27 16:51:43 -05:00
myIncludeOuterEvent = theIncludeOuterEvent ;
2014-02-21 21:06:11 -05:00
}
2014-03-22 12:33:07 -04:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( myJsonMode ) {
myDt . setValueAsString ( theValue ) ;
2017-08-13 14:39:47 -04:00
} else {
2015-06-12 08:27:03 -04:00
// IGNORE - don't handle this as an error, we process these as XML events
2014-03-22 12:33:07 -04:00
}
}
2015-04-13 08:32:49 -04:00
protected void doPop ( ) {
pop ( ) ;
}
2015-04-21 13:30:58 -04:00
2014-03-22 12:33:07 -04:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-03-22 12:33:07 -04:00
if ( myJsonMode ) {
2015-04-13 08:32:49 -04:00
doPop ( ) ;
2014-03-22 12:33:07 -04:00
return ;
}
2014-03-24 08:32:28 -04:00
super . endingElement ( ) ;
2014-03-22 12:33:07 -04:00
}
2016-02-08 22:05:17 -05:00
@Override
public void enteringNewElement ( String theNamespaceUri , String theLocalPart ) throws DataFormatException {
// IGNORE - don't handle this as an error, we process these as XML events
}
2014-06-03 16:52:21 -04:00
@Override
protected IElement getCurrentElement ( ) {
return myDt ;
}
2016-02-08 22:05:17 -05:00
public XhtmlDt getDt ( ) {
return myDt ;
}
2014-02-21 21:06:11 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void xmlEvent ( XMLEvent theEvent ) {
2014-02-27 16:51:43 -05:00
if ( theEvent . isEndElement ( ) ) {
myDepth - - ;
}
if ( myIncludeOuterEvent | | myDepth > 0 ) {
myEvents . add ( theEvent ) ;
}
2014-02-22 15:33:02 -05:00
2014-02-27 11:57:50 -05:00
if ( theEvent . isStartElement ( ) ) {
myDepth + + ;
}
2014-03-06 17:12:05 -05:00
2014-02-27 11:57:50 -05:00
if ( theEvent . isEndElement ( ) ) {
if ( myDepth = = 0 ) {
2017-10-16 17:22:50 -04:00
String eventsAsString = XmlUtil . encode ( myEvents ) ;
myDt . setValue ( eventsAsString ) ;
2015-04-13 08:32:49 -04:00
doPop ( ) ;
2014-02-27 11:57:50 -05:00
}
2014-02-21 21:06:11 -05:00
}
}
2014-02-19 11:59:12 -05:00
}
2016-02-08 22:05:17 -05:00
private class XhtmlStateHl7Org extends XhtmlState {
private IBaseXhtml myHl7OrgDatatype ;
private XhtmlStateHl7Org ( PreResourceState thePreResourceState , IBaseXhtml theHl7OrgDatatype ) {
super ( thePreResourceState , new XhtmlDt ( ) , true ) ;
myHl7OrgDatatype = theHl7OrgDatatype ;
}
@Override
public void doPop ( ) {
// TODO: this is not very efficient
String value = getDt ( ) . getValueAsString ( ) ;
myHl7OrgDatatype . setValueAsString ( value ) ;
super . doPop ( ) ;
}
}
2019-09-30 20:14:36 -04:00
/ * *
* @param theResourceType May be null
* /
static < T extends IBaseResource > ParserState < T > getPreResourceInstance ( IParser theParser , Class < T > theResourceType , FhirContext theContext , boolean theJsonMode , IParserErrorHandler theErrorHandler )
throws DataFormatException {
ParserState < T > retVal = new ParserState < T > ( theParser , theContext , theJsonMode , theErrorHandler ) ;
if ( theResourceType = = null ) {
if ( theContext . getVersion ( ) . getVersion ( ) . isRi ( ) ) {
retVal . push ( retVal . new PreResourceStateHl7Org ( theResourceType ) ) ;
} else {
retVal . push ( retVal . new PreResourceStateHapi ( theResourceType ) ) ;
}
} else {
if ( IResource . class . isAssignableFrom ( theResourceType ) ) {
retVal . push ( retVal . new PreResourceStateHapi ( theResourceType ) ) ;
} else {
retVal . push ( retVal . new PreResourceStateHl7Org ( theResourceType ) ) ;
}
}
return retVal ;
}
static ParserState < TagList > getPreTagListInstance ( IParser theParser , FhirContext theContext , boolean theJsonMode , IParserErrorHandler theErrorHandler ) {
ParserState < TagList > retVal = new ParserState < TagList > ( theParser , theContext , theJsonMode , theErrorHandler ) ;
retVal . push ( retVal . new PreTagListState ( ) ) ;
return retVal ;
}
2014-02-18 08:26:49 -05:00
}