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
* % %
* Copyright ( C ) 2014 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 %
* /
2014-12-10 22:02:31 -05:00
import static org.apache.commons.lang3.StringUtils.* ;
2014-03-16 15:09:30 -04:00
2014-02-22 15:33:02 -05:00
import java.util.ArrayList ;
2014-03-16 15:09:30 -04:00
import java.util.HashMap ;
2014-02-22 15:33:02 -05:00
import java.util.List ;
2014-03-16 15:09:30 -04:00
import java.util.Map ;
2014-02-21 21:06:11 -05:00
import javax.xml.stream.events.StartElement ;
import javax.xml.stream.events.XMLEvent ;
2014-02-27 11:57:50 -05:00
import org.apache.commons.lang3.StringUtils ;
2014-03-16 15:09:30 -04:00
import org.apache.commons.lang3.Validate ;
2014-12-10 22:02:31 -05:00
import org.hl7.fhir.instance.model.Element ;
import org.hl7.fhir.instance.model.IBase ;
2014-12-10 17:40:47 -05:00
import org.hl7.fhir.instance.model.IBaseResource ;
2014-12-10 22:02:31 -05:00
import org.hl7.fhir.instance.model.IPrimitiveType ;
2014-02-27 11:57:50 -05:00
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.BaseRuntimeChildDefinition ;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition ;
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.BaseRuntimeElementDefinition ;
import ca.uhn.fhir.context.FhirContext ;
2014-02-23 18:13:59 -05:00
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition ;
2014-03-17 08:57:57 -04:00
import ca.uhn.fhir.context.RuntimeElemContainedResources ;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition ;
2014-02-22 15:33:02 -05:00
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition ;
2014-02-20 12:13:05 -05:00
import ca.uhn.fhir.context.RuntimeResourceBlockDefinition ;
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.RuntimeResourceDefinition ;
2014-02-19 17:33:46 -05:00
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition ;
2014-02-27 16:51:43 -05:00
import ca.uhn.fhir.model.api.BaseBundle ;
2014-02-26 17:13:49 -05:00
import ca.uhn.fhir.model.api.Bundle ;
2014-02-27 16:51:43 -05:00
import ca.uhn.fhir.model.api.BundleEntry ;
2014-03-27 08:51:02 -04:00
import ca.uhn.fhir.model.api.ExtensionDt ;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.model.api.ICompositeDatatype ;
2014-02-22 15:33:02 -05:00
import ca.uhn.fhir.model.api.IElement ;
2014-07-04 09:27:36 -04:00
import ca.uhn.fhir.model.api.IIdentifiableElement ;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.model.api.IPrimitiveDatatype ;
2014-02-27 07:39:36 -05:00
import ca.uhn.fhir.model.api.IResource ;
2014-02-20 12:13:05 -05:00
import ca.uhn.fhir.model.api.IResourceBlock ;
2014-02-26 17:13:49 -05:00
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions ;
2014-04-14 08:40:30 -04:00
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum ;
2014-05-11 21:46:36 -04:00
import ca.uhn.fhir.model.api.Tag ;
2014-05-07 08:18:43 -04:00
import ca.uhn.fhir.model.api.TagList ;
2014-03-17 08:57:57 -04:00
import ca.uhn.fhir.model.dstu.composite.ContainedDt ;
2014-03-10 18:17:30 -04:00
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt ;
2014-05-28 07:30:40 -04:00
import ca.uhn.fhir.model.dstu.resource.Binary ;
2014-03-16 15:09:30 -04:00
import ca.uhn.fhir.model.primitive.IdDt ;
2014-05-21 18:12:00 -04:00
import ca.uhn.fhir.model.primitive.InstantDt ;
2014-02-24 11:46:08 -05:00
import ca.uhn.fhir.model.primitive.XhtmlDt ;
2014-04-14 08:40:30 -04:00
import ca.uhn.fhir.rest.server.Constants ;
2014-08-19 07:48:06 -04:00
import ca.uhn.fhir.util.IModelVisitor ;
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 ) ;
private FhirContext myContext ;
2014-05-05 05:57:43 -07:00
private boolean myJsonMode ;
2014-02-27 07:39:36 -05:00
private T myObject ;
2014-02-21 21:06:11 -05:00
private BaseState myState ;
2014-02-19 17:33:46 -05:00
2014-03-22 12:33:07 -04:00
private ParserState ( FhirContext theContext , boolean theJsonMode ) {
2014-02-21 21:06:11 -05:00
myContext = theContext ;
2014-03-22 12:33:07 -04:00
myJsonMode = theJsonMode ;
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
}
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
2014-02-27 11:57:50 -05: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
2014-03-10 18:17:30 -04:00
public void enteringNewElementExtension ( StartElement theElem , String theUrlAttr , boolean theIsModifier ) {
myState . enteringNewElementExtension ( theElem , theUrlAttr , theIsModifier ) ;
2014-02-22 15:33:02 -05:00
}
2014-03-22 12:33:07 -04:00
@SuppressWarnings ( " unchecked " )
2014-02-27 07:39:36 -05:00
public T getObject ( ) {
2014-03-22 12:33:07 -04:00
return ( T ) myState . getCurrentElement ( ) ;
2014-02-19 11:59:12 -05:00
}
2014-02-21 21:06:11 -05:00
public boolean isComplete ( ) {
return myObject ! = null ;
2014-02-19 11:59:12 -05:00
}
2014-05-05 05:57:43 -07:00
public boolean isPreResource ( ) {
return myState . isPreResource ( ) ;
}
2014-06-03 16:52:21 -04:00
private void pop ( ) {
myState = myState . myStack ;
myState . wereBack ( ) ;
}
private void push ( BaseState theState ) {
theState . setStack ( myState ) ;
myState = theState ;
}
private void putPlacerResourceInDeletedEntry ( BundleEntry entry ) {
IdDt id = null ;
if ( entry . getLinkSelf ( ) ! = null & & entry . getLinkSelf ( ) . isEmpty ( ) = = false ) {
id = new IdDt ( entry . getLinkSelf ( ) . getValue ( ) ) ;
} else {
id = entry . getId ( ) ;
}
IResource resource = entry . getResource ( ) ;
if ( resource = = null & & id ! = null & & isNotBlank ( id . getResourceType ( ) ) ) {
2014-06-20 16:54:09 -04:00
String resourceType = id . getResourceType ( ) ;
RuntimeResourceDefinition def = myContext . getResourceDefinition ( resourceType ) ;
if ( def = = null ) {
throw new DataFormatException ( " Entry references unknown resource type: " + resourceType ) ;
}
2014-12-10 17:40:47 -05:00
resource = ( IResource ) def . newInstance ( ) ;
2014-06-03 16:52:21 -04:00
resource . setId ( id ) ;
entry . setResource ( resource ) ;
}
if ( resource ! = null ) {
resource . getResourceMetadata ( ) . put ( ResourceMetadataKeyEnum . DELETED_AT , entry . getDeletedAt ( ) ) ;
resource . getResourceMetadata ( ) . put ( ResourceMetadataKeyEnum . VERSION_ID , id ) ;
}
}
2014-02-27 16:51:43 -05:00
public void string ( String theData ) {
myState . string ( theData ) ;
}
public boolean verifyNamespace ( String theExpect , String theActual ) {
2014-03-24 08:32:28 -04:00
if ( myJsonMode ) {
return true ;
}
2014-02-27 16:51:43 -05:00
return StringUtils . equals ( theExpect , theActual ) ;
}
/ * *
2014-09-30 11:57:15 -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
2014-02-27 16:51:43 -05:00
* /
public void xmlEvent ( XMLEvent theNextEvent ) {
myState . xmlEvent ( theNextEvent ) ;
}
2014-12-10 17:40:47 -05:00
public static ParserState < Bundle > getPreAtomInstance ( FhirContext theContext , Class < ? extends IBaseResource > theResourceType , boolean theJsonMode ) throws DataFormatException {
2014-03-22 12:33:07 -04:00
ParserState < Bundle > retVal = new ParserState < Bundle > ( theContext , theJsonMode ) ;
2014-04-30 18:39:33 -04:00
retVal . push ( retVal . new PreAtomState ( theResourceType ) ) ;
2014-02-27 07:39:36 -05:00
return retVal ;
}
2014-03-07 16:23:49 -05:00
/ * *
* @param theResourceType
* May be null
* /
2014-12-10 17:40:47 -05:00
public static < T extends IBaseResource > ParserState < T > getPreResourceInstance ( Class < T > theResourceType , FhirContext theContext , boolean theJsonMode ) throws DataFormatException {
2014-03-22 12:33:07 -04:00
ParserState < T > retVal = new ParserState < T > ( theContext , theJsonMode ) ;
2014-03-07 16:23:49 -05:00
retVal . push ( retVal . new PreResourceState ( theResourceType ) ) ;
2014-02-27 16:51:43 -05:00
return retVal ;
}
2014-02-26 17:13:49 -05:00
2014-05-07 08:18:43 -04:00
public static ParserState < TagList > getPreTagListInstance ( FhirContext theContext , boolean theJsonMode ) {
ParserState < TagList > retVal = new ParserState < TagList > ( theContext , theJsonMode ) ;
retVal . push ( retVal . new PreTagListState ( ) ) ;
return retVal ;
}
2014-02-27 16:51:43 -05:00
public class AtomAuthorState extends BaseState {
2014-02-26 17:13:49 -05:00
2014-02-27 16:51:43 -05:00
private BaseBundle myInstance ;
public AtomAuthorState ( BaseBundle theEntry ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-02-27 16:51:43 -05:00
myInstance = theEntry ;
2014-02-18 08:26:49 -05:00
}
2014-02-19 11:59:12 -05:00
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 ( ) ;
}
2014-02-19 11:59:12 -05:00
2014-02-26 17:13:49 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-02-27 16:51:43 -05:00
if ( " name " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myInstance . getAuthorName ( ) ) ) ;
} else if ( " uri " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myInstance . getAuthorUri ( ) ) ) ;
} else {
throw new DataFormatException ( " Unexpected element: " + theLocalPart ) ;
}
}
}
2014-03-06 17:12:05 -05:00
public class AtomCategoryState extends BaseState {
2014-05-05 05:57:43 -07:00
private static final int STATE_LABEL = 2 ;
private static final int STATE_NONE = 0 ;
private static final int STATE_SCHEME = 3 ;
private static final int STATE_TERM = 1 ;
2014-07-04 09:27:36 -04:00
2014-05-05 05:57:43 -07:00
private int myCatState = STATE_NONE ;
2014-09-30 11:57:15 -04:00
private TagList myTagList ;
private String myTerm ;
private String myLabel ;
private String myScheme ;
2014-03-06 17:12:05 -05:00
2014-09-30 11:57:15 -04:00
public AtomCategoryState ( TagList theTagList ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-09-30 11:57:15 -04:00
myTagList = theTagList ;
2014-03-06 17:12:05 -05:00
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( " term " . equals ( theName ) ) {
2014-09-30 11:57:15 -04:00
myTerm = theValue ;
2014-03-06 17:12:05 -05:00
} else if ( " label " . equals ( theName ) ) {
2014-09-30 11:57:15 -04:00
myLabel = theValue ;
2014-03-06 17:12:05 -05:00
} else if ( " scheme " . equals ( theName ) ) {
2014-09-30 11:57:15 -04:00
myScheme = theValue ;
2014-05-05 05:57:43 -07:00
} else if ( " value " . equals ( theName ) ) {
2014-05-07 08:18:43 -04:00
/ *
2014-09-30 11:57:15 -04:00
* This handles XML parsing , which is odd for this quasi - resource type , since the tag has three values instead of one like everything else .
2014-05-07 08:18:43 -04:00
* /
2014-05-05 05:57:43 -07:00
switch ( myCatState ) {
case STATE_LABEL :
2014-09-30 11:57:15 -04:00
myLabel = theValue ;
2014-05-05 05:57:43 -07:00
break ;
case STATE_TERM :
2014-09-30 11:57:15 -04:00
myTerm = theValue ;
2014-05-05 05:57:43 -07:00
break ;
case STATE_SCHEME :
2014-09-30 11:57:15 -04:00
myScheme = theValue ;
2014-05-05 05:57:43 -07:00
break ;
default :
super . string ( theValue ) ;
break ;
}
2014-03-06 17:12:05 -05:00
}
}
2014-03-16 15:09:30 -04:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-05-05 05:57:43 -07:00
if ( myCatState ! = STATE_NONE ) {
myCatState = STATE_NONE ;
} else {
2014-09-30 11:57:15 -04:00
if ( isNotEmpty ( myScheme ) | | isNotBlank ( myTerm ) | | isNotBlank ( myLabel ) ) {
myTagList . addTag ( myScheme , myTerm , myLabel ) ;
}
2014-05-05 05:57:43 -07:00
pop ( ) ;
}
2014-03-16 15:09:30 -04:00
}
@Override
2014-05-05 05:57:43 -07:00
public void enteringNewElement ( String theNamespaceURI , String theName ) throws DataFormatException {
if ( myCatState ! = STATE_NONE ) {
throw new DataFormatException ( " Unexpected element in entry: " + theName ) ;
}
if ( " term " . equals ( theName ) ) {
myCatState = STATE_TERM ;
} else if ( " label " . equals ( theName ) ) {
myCatState = STATE_LABEL ;
} else if ( " scheme " . equals ( theName ) ) {
myCatState = STATE_SCHEME ;
}
2014-03-16 15:09:30 -04:00
}
2014-03-06 17:12:05 -05:00
}
2014-06-03 16:52:21 -04:00
public class AtomDeletedEntryState extends AtomEntryState {
2014-12-10 17:40:47 -05:00
public AtomDeletedEntryState ( Bundle theInstance , Class < ? extends IBaseResource > theResourceType ) {
2014-06-03 16:52:21 -04:00
super ( theInstance , theResourceType ) ;
2014-05-22 18:38:29 -04:00
}
2014-05-28 07:30:40 -04:00
2014-06-03 16:52:21 -04:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( " ref " . equals ( theName ) ) {
getEntry ( ) . setId ( new IdDt ( theValue ) ) ;
} else if ( " when " . equals ( theName ) ) {
getEntry ( ) . setDeleted ( new InstantDt ( theValue ) ) ;
}
2014-05-22 18:38:29 -04:00
}
2014-05-28 07:30:40 -04:00
2014-07-11 18:27:27 -04:00
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
if ( " by " . equals ( theLocalPart ) & & verifyNamespace ( XmlParser . TOMBSTONES_NS , theNamespaceURI ) ) {
push ( new AtomDeletedEntryByState ( getEntry ( ) ) ) ;
} else if ( " comment " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( getEntry ( ) . getDeletedComment ( ) ) ) ;
} else {
2014-07-13 21:59:41 -04:00
super . enteringNewElement ( theNamespaceURI , theLocalPart ) ;
2014-07-11 18:27:27 -04:00
}
}
2014-06-03 16:52:21 -04:00
@Override
public void endingElement ( ) throws DataFormatException {
putPlacerResourceInDeletedEntry ( getEntry ( ) ) ;
super . endingElement ( ) ;
}
}
2014-07-11 18:27:27 -04:00
public class AtomDeletedEntryByState extends BaseState {
private BundleEntry myEntry ;
public AtomDeletedEntryByState ( BundleEntry theEntry ) {
super ( null ) ;
myEntry = theEntry ;
}
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
if ( " name " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myEntry . getDeletedByName ( ) ) ) ;
} else if ( " email " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myEntry . getDeletedByEmail ( ) ) ) ;
} else {
throw new DataFormatException ( " Unexpected element in entry: " + theLocalPart ) ;
}
}
@Override
public void endingElement ( ) throws DataFormatException {
pop ( ) ;
}
}
2014-06-03 16:52:21 -04:00
private class AtomDeletedJsonWhenState extends BaseState {
private String myData ;
private IPrimitiveDatatype < ? > myPrimitive ;
public AtomDeletedJsonWhenState ( IPrimitiveDatatype < ? > thePrimitive ) {
super ( null ) ;
Validate . notNull ( thePrimitive , " thePrimitive " ) ;
myPrimitive = thePrimitive ;
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
myData = theValue ;
}
@Override
public void endingElement ( ) throws DataFormatException {
myPrimitive . setValueAsString ( myData ) ;
pop ( ) ;
}
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
throw new DataFormatException ( " Unexpected nested element in atom tag: " + theLocalPart ) ;
}
@Override
protected IElement getCurrentElement ( ) {
return null ;
2014-05-22 18:38:29 -04:00
}
2014-06-03 16:52:21 -04:00
2014-05-22 18:38:29 -04:00
}
2014-02-27 16:51:43 -05:00
public class AtomEntryState extends BaseState {
2014-06-03 16:52:21 -04:00
private boolean myDeleted ;
2014-02-27 16:51:43 -05:00
private BundleEntry myEntry ;
2014-12-10 17:40:47 -05:00
private Class < ? extends IBaseResource > myResourceType ;
2014-02-27 16:51:43 -05:00
2014-12-10 17:40:47 -05:00
public AtomEntryState ( Bundle theInstance , Class < ? extends IBaseResource > theResourceType ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-02-27 16:51:43 -05:00
myEntry = new BundleEntry ( ) ;
2014-04-30 18:39:33 -04:00
myResourceType = theResourceType ;
2014-02-27 16:51:43 -05:00
theInstance . getEntries ( ) . add ( myEntry ) ;
2014-02-26 17:13:49 -05:00
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-04-14 08:40:30 -04:00
populateResourceMetadata ( ) ;
2014-02-27 16:51:43 -05:00
pop ( ) ;
2014-05-22 18:38:29 -04:00
if ( myDeleted ) {
putPlacerResourceInDeletedEntry ( myEntry ) ;
}
2014-02-26 17:13:49 -05:00
}
2014-05-05 05:57:43 -07:00
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
if ( " title " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myEntry . getTitle ( ) ) ) ;
} else if ( " id " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myEntry . getId ( ) ) ) ;
} else if ( " link " . equals ( theLocalPart ) ) {
push ( new AtomLinkState ( myEntry ) ) ;
} else if ( " updated " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myEntry . getUpdated ( ) ) ) ;
} else if ( " published " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myEntry . getPublished ( ) ) ) ;
} else if ( " author " . equals ( theLocalPart ) ) {
push ( new AtomAuthorState ( myEntry ) ) ;
} else if ( " content " . equals ( theLocalPart ) ) {
push ( new PreResourceState ( myEntry , myResourceType ) ) ;
} else if ( " summary " . equals ( theLocalPart ) ) {
push ( new XhtmlState ( getPreResourceState ( ) , myEntry . getSummary ( ) , false ) ) ;
} else if ( " category " . equals ( theLocalPart ) ) {
2014-09-30 11:57:15 -04:00
push ( new AtomCategoryState ( myEntry . getCategories ( ) ) ) ;
2014-05-21 18:12:00 -04:00
} else if ( " deleted " . equals ( theLocalPart ) & & myJsonMode ) {
// JSON and XML deleted entries are completely different for some reason
2014-05-22 18:38:29 -04:00
myDeleted = true ;
2014-05-21 18:12:00 -04:00
push ( new AtomDeletedJsonWhenState ( myEntry . getDeletedAt ( ) ) ) ;
2014-05-05 05:57:43 -07:00
} else {
throw new DataFormatException ( " Unexpected element in entry: " + theLocalPart ) ;
}
// TODO: handle category
}
2014-06-03 16:52:21 -04:00
protected BundleEntry getEntry ( ) {
return myEntry ;
}
2014-05-22 18:38:29 -04:00
@SuppressWarnings ( " deprecation " )
2014-04-14 08:40:30 -04:00
private void populateResourceMetadata ( ) {
if ( myEntry . getResource ( ) = = null ) {
return ;
}
2014-05-26 09:09:54 -04:00
IdDt id = myEntry . getId ( ) ;
2014-05-28 07:30:40 -04:00
if ( id ! = null & & id . isEmpty ( ) = = false ) {
2014-05-26 09:09:54 -04:00
myEntry . getResource ( ) . setId ( id ) ;
}
2014-05-28 07:30:40 -04:00
2014-06-12 11:42:28 -04:00
Map < ResourceMetadataKeyEnum < ? > , Object > metadata = myEntry . getResource ( ) . getResourceMetadata ( ) ;
2014-04-14 08:40:30 -04:00
if ( myEntry . getPublished ( ) . isEmpty ( ) = = false ) {
2014-06-12 11:42:28 -04:00
ResourceMetadataKeyEnum . PUBLISHED . put ( myEntry . getResource ( ) , myEntry . getPublished ( ) ) ;
2014-04-14 08:40:30 -04:00
}
if ( myEntry . getUpdated ( ) . isEmpty ( ) = = false ) {
2014-06-12 11:42:28 -04:00
ResourceMetadataKeyEnum . UPDATED . put ( myEntry . getResource ( ) , myEntry . getUpdated ( ) ) ;
2014-04-14 08:40:30 -04:00
}
2014-07-04 09:27:36 -04:00
2014-07-03 18:02:14 -04:00
ResourceMetadataKeyEnum . TITLE . put ( myEntry . getResource ( ) , myEntry . getTitle ( ) . getValue ( ) ) ;
2014-07-04 09:27:36 -04:00
2014-05-07 08:18:43 -04:00
if ( myEntry . getCategories ( ) . isEmpty ( ) = = false ) {
TagList tagList = new TagList ( ) ;
for ( Tag next : myEntry . getCategories ( ) ) {
tagList . add ( next ) ;
}
2014-06-12 11:42:28 -04:00
ResourceMetadataKeyEnum . TAG_LIST . put ( myEntry . getResource ( ) , tagList ) ;
2014-05-07 08:18:43 -04:00
}
2014-04-14 08:40:30 -04:00
if ( ! myEntry . getLinkSelf ( ) . isEmpty ( ) ) {
String linkSelfValue = myEntry . getLinkSelf ( ) . getValue ( ) ;
2014-05-26 09:09:54 -04:00
IdDt linkSelf = new IdDt ( linkSelfValue ) ;
myEntry . getResource ( ) . setId ( linkSelf ) ;
2014-06-23 09:04:48 -04:00
if ( isNotBlank ( linkSelf . getVersionIdPart ( ) ) ) {
2014-05-26 09:09:54 -04:00
metadata . put ( ResourceMetadataKeyEnum . VERSION_ID , linkSelf ) ;
2014-04-14 08:40:30 -04:00
}
}
2014-08-16 17:46:30 -04:00
if ( ! myEntry . getLinkAlternate ( ) . isEmpty ( ) ) {
ResourceMetadataKeyEnum . LINK_ALTERNATE . put ( myEntry . getResource ( ) , myEntry . getLinkAlternate ( ) . getValue ( ) ) ;
}
if ( ! myEntry . getLinkSearch ( ) . isEmpty ( ) ) {
ResourceMetadataKeyEnum . LINK_SEARCH . put ( myEntry . getResource ( ) , myEntry . getLinkSearch ( ) . getValue ( ) ) ;
}
2014-04-14 08:40:30 -04:00
}
2014-02-18 08:26:49 -05:00
}
2014-05-22 18:38:29 -04:00
2014-02-27 11:57:50 -05:00
private class AtomLinkState extends BaseState {
2014-02-27 16:51:43 -05:00
private BundleEntry myEntry ;
2014-02-27 11:57:50 -05:00
private String myHref ;
private Bundle myInstance ;
2014-02-27 16:51:43 -05:00
private String myRel ;
2014-02-27 11:57:50 -05:00
public AtomLinkState ( Bundle theInstance ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-02-27 11:57:50 -05:00
myInstance = theInstance ;
}
2014-02-27 10:20:25 -05:00
2014-02-27 16:51:43 -05:00
public AtomLinkState ( BundleEntry theEntry ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-02-27 16:51:43 -05:00
myEntry = theEntry ;
}
2014-02-27 10:20:25 -05:00
@Override
2014-02-27 16:51:43 -05:00
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( " rel " . equals ( theName ) ) {
2014-02-27 11:57:50 -05:00
myRel = theValue ;
2014-02-27 16:51:43 -05:00
} else if ( " href " . equals ( theName ) ) {
2014-02-27 11:57:50 -05:00
myHref = theValue ;
}
2014-02-27 10:20:25 -05:00
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-02-27 16:51:43 -05:00
if ( myInstance ! = null ) {
if ( " self " . equals ( myRel ) ) {
myInstance . getLinkSelf ( ) . setValueAsString ( myHref ) ;
} else if ( " first " . equals ( myRel ) ) {
myInstance . getLinkFirst ( ) . setValueAsString ( myHref ) ;
} else if ( " previous " . equals ( myRel ) ) {
myInstance . getLinkPrevious ( ) . setValueAsString ( myHref ) ;
} else if ( " next " . equals ( myRel ) ) {
myInstance . getLinkNext ( ) . setValueAsString ( myHref ) ;
} else if ( " last " . equals ( myRel ) ) {
myInstance . getLinkLast ( ) . setValueAsString ( myHref ) ;
} else if ( " fhir-base " . equals ( myRel ) ) {
myInstance . getLinkBase ( ) . setValueAsString ( myHref ) ;
}
} else {
2014-05-26 09:09:54 -04:00
if ( " self " . equals ( myRel ) ) {
myEntry . getLinkSelf ( ) . setValueAsString ( myHref ) ;
2014-07-21 14:57:37 -04:00
} else if ( " search " . equals ( myRel ) ) {
myEntry . getLinkSearch ( ) . setValueAsString ( myHref ) ;
2014-05-26 09:09:54 -04:00
} else if ( " alternate " . equals ( myRel ) ) {
myEntry . getLinkAlternate ( ) . setValueAsString ( myHref ) ;
}
2014-02-27 11:57:50 -05:00
}
2014-02-27 10:20:25 -05:00
pop ( ) ;
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-03-19 17:38:31 -04:00
throw new DataFormatException ( " Found unexpected element content ' " + theLocalPart + " ' within <link> " ) ;
2014-02-27 10:20:25 -05:00
}
}
2014-02-27 16:51:43 -05:00
private class AtomPrimitiveState extends BaseState {
private String myData ;
private IPrimitiveDatatype < ? > myPrimitive ;
public AtomPrimitiveState ( IPrimitiveDatatype < ? > thePrimitive ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
Validate . notNull ( thePrimitive , " thePrimitive " ) ;
2014-02-27 16:51:43 -05:00
myPrimitive = thePrimitive ;
}
2014-05-21 18:12:00 -04:00
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( myJsonMode ) {
string ( theValue ) ;
}
super . attributeValue ( theName , theValue ) ;
}
2014-02-27 16:51:43 -05:00
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-02-27 16:51:43 -05:00
myPrimitive . setValueAsString ( myData ) ;
pop ( ) ;
}
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
throw new DataFormatException ( " Unexpected nested element in atom tag: " + theLocalPart ) ;
}
2014-06-03 16:52:21 -04:00
@Override
protected IElement getCurrentElement ( ) {
return null ;
}
2014-02-27 16:51:43 -05:00
@Override
public void string ( String theData ) {
if ( myData = = null ) {
myData = theData ;
} else {
// this shouldn't generally happen so it's ok that it's
// inefficient
myData = myData + theData ;
}
}
2014-05-21 18:12:00 -04:00
}
2014-05-22 18:38:29 -04:00
2014-02-26 17:13:49 -05:00
private class AtomState extends BaseState {
private Bundle myInstance ;
2014-12-10 17:40:47 -05:00
private Class < ? extends IBaseResource > myResourceType ;
2014-02-26 17:13:49 -05:00
2014-12-10 17:40:47 -05:00
public AtomState ( Bundle theInstance , Class < ? extends IBaseResource > theResourceType ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-02-26 17:13:49 -05:00
myInstance = theInstance ;
2014-04-30 18:39:33 -04:00
myResourceType = theResourceType ;
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
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-02-27 12:04:19 -05:00
if ( " entry " . equals ( theLocalPart ) & & verifyNamespace ( XmlParser . ATOM_NS , theNamespaceURI ) ) {
2014-04-30 18:39:33 -04:00
push ( new AtomEntryState ( myInstance , myResourceType ) ) ;
2014-03-04 16:41:18 -05:00
} else if ( theLocalPart . equals ( " published " ) ) {
push ( new AtomPrimitiveState ( myInstance . getPublished ( ) ) ) ;
2014-02-27 12:04:19 -05:00
} else if ( theLocalPart . equals ( " title " ) ) {
2014-02-26 17:13:49 -05:00
push ( new AtomPrimitiveState ( myInstance . getTitle ( ) ) ) ;
2014-02-27 10:20:25 -05:00
} else if ( " id " . equals ( theLocalPart ) ) {
2014-03-16 15:09:30 -04:00
push ( new AtomPrimitiveState ( myInstance . getBundleId ( ) ) ) ;
2014-02-27 10:20:25 -05:00
} else if ( " link " . equals ( theLocalPart ) ) {
2014-02-27 11:57:50 -05:00
push ( new AtomLinkState ( myInstance ) ) ;
2014-05-05 05:57:43 -07:00
} else if ( " totalResults " . equals ( theLocalPart ) & & ( verifyNamespace ( XmlParser . OPENSEARCH_NS , theNamespaceURI ) | | verifyNamespace ( Constants . OPENSEARCH_NS_OLDER , theNamespaceURI ) ) ) {
2014-02-27 11:57:50 -05:00
push ( new AtomPrimitiveState ( myInstance . getTotalResults ( ) ) ) ;
} else if ( " updated " . equals ( theLocalPart ) ) {
push ( new AtomPrimitiveState ( myInstance . getUpdated ( ) ) ) ;
} else if ( " author " . equals ( theLocalPart ) ) {
push ( new AtomAuthorState ( myInstance ) ) ;
2014-08-19 07:48:06 -04:00
} else if ( " category " . equals ( theLocalPart ) ) {
2014-09-30 11:57:15 -04:00
push ( new AtomCategoryState ( myInstance . getCategories ( ) ) ) ;
2014-05-21 18:12:00 -04:00
} else if ( " deleted-entry " . equals ( theLocalPart ) & & verifyNamespace ( XmlParser . TOMBSTONES_NS , theNamespaceURI ) ) {
2014-05-22 18:38:29 -04:00
push ( new AtomDeletedEntryState ( myInstance , myResourceType ) ) ;
2014-02-27 16:51:43 -05:00
} else {
2014-05-05 05:57:43 -07:00
if ( theNamespaceURI ! = null ) {
throw new DataFormatException ( " Unexpected element: { " + theNamespaceURI + " } " + theLocalPart ) ;
} else {
throw new DataFormatException ( " Unexpected element: " + theLocalPart ) ;
}
2014-02-27 12:04:19 -05:00
}
2014-02-27 11:57:50 -05:00
// TODO: handle category and DSig
2014-02-26 17:13:49 -05:00
}
@Override
protected IElement getCurrentElement ( ) {
2014-02-27 10:20:25 -05:00
return myInstance ;
2014-02-26 17:13:49 -05:00
}
}
2014-02-27 10:20:25 -05:00
2014-02-20 12:13:05 -05:00
private abstract class BaseState {
2014-02-26 17:13:49 -05:00
2014-03-16 15:09:30 -04:00
private PreResourceState myPreResourceState ;
2014-02-20 12:13:05 -05:00
private BaseState myStack ;
2014-02-18 08:26:49 -05:00
2014-03-16 15:09:30 -04:00
public BaseState ( PreResourceState thePreResourceState ) {
super ( ) ;
myPreResourceState = thePreResourceState ;
}
2014-08-28 07:53:41 -04:00
@SuppressWarnings ( " unused " )
2014-02-27 16:51:43 -05:00
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
2014-02-27 11:57:50 -05:00
// ignore by default
}
2014-02-21 21:06:11 -05:00
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-02-27 11:57:50 -05:00
// ignore by default
}
2014-02-19 11:59:12 -05:00
2014-08-28 07:53:41 -04:00
@SuppressWarnings ( " unused " )
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
// ignore by default
}
2014-02-18 08:26:49 -05:00
2014-02-23 18:13:59 -05:00
/ * *
* Default implementation just handles undeclared extensions
* /
2014-08-28 07:53:41 -04:00
@SuppressWarnings ( " unused " )
2014-07-04 09:27:36 -04:00
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier ) {
2014-03-16 15:09:30 -04:00
if ( myPreResourceState ! = null & & getCurrentElement ( ) instanceof ISupportsUndeclaredExtensions ) {
2014-03-27 08:51:02 -04:00
ExtensionDt newExtension = new ExtensionDt ( theIsModifier , theUrlAttr ) ;
2014-03-10 18:17:30 -04:00
ISupportsUndeclaredExtensions elem = ( ISupportsUndeclaredExtensions ) getCurrentElement ( ) ;
2014-08-15 09:19:07 -04:00
elem . addUndeclaredExtension ( newExtension ) ;
2014-03-16 15:09:30 -04:00
ExtensionState newState = new ExtensionState ( myPreResourceState , newExtension ) ;
2014-02-22 15:33:02 -05:00
push ( newState ) ;
2014-02-28 13:27:35 -05:00
} else {
2014-03-10 18:17:30 -04:00
throw new DataFormatException ( " Type " + getCurrentElement ( ) + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr ) ;
2014-02-22 15:33:02 -05:00
}
}
2014-06-03 16:52:21 -04:00
protected Object getCurrentElement ( ) {
return null ;
}
2014-03-16 15:09:30 -04:00
public PreResourceState getPreResourceState ( ) {
return myPreResourceState ;
}
2014-05-05 05:57:43 -07:00
public boolean isPreResource ( ) {
return false ;
}
2014-02-20 12:13:05 -05:00
public void setStack ( BaseState theState ) {
myStack = theState ;
}
2014-08-27 08:55:00 -04:00
/ * *
2014-09-30 11:57:15 -04:00
* @param theData
* The string value
2014-08-27 08:55:00 -04:00
* /
2014-07-03 18:02:14 -04:00
public void string ( String theData ) {
2014-02-27 11:57:50 -05:00
// ignore by default
}
2014-02-27 16:51:43 -05:00
public void wereBack ( ) {
// allow an implementor to override
}
2014-08-27 08:55:00 -04:00
/ * *
2014-09-30 11:57:15 -04:00
* @param theNextEvent
* The XML event
2014-08-27 08:55:00 -04:00
* /
2014-07-03 18:02:14 -04:00
public void xmlEvent ( XMLEvent theNextEvent ) {
2014-02-27 11:57:50 -05:00
// ignore
}
2014-06-03 16:52:21 -04:00
}
private class BinaryResourceState extends BaseState {
private static final int SUBSTATE_CONTENT = 2 ;
private static final int SUBSTATE_CT = 1 ;
private String myData ;
private Binary myInstance ;
private int mySubState = 0 ;
public BinaryResourceState ( PreResourceState thePreResourceState , Binary theInstance ) {
super ( thePreResourceState ) ;
myInstance = theInstance ;
}
@Override
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
2014-09-25 10:36:29 +02:00
if ( " id " . equals ( theName ) ) {
if ( myInstance instanceof IIdentifiableElement ) {
( ( IIdentifiableElement ) myInstance ) . setElementSpecificId ( ( theValue ) ) ;
2014-12-10 17:40:47 -05:00
} else if ( myInstance instanceof IBaseResource ) {
2014-12-10 22:02:31 -05:00
( myInstance ) . setId ( new IdDt ( theValue ) ) ;
2014-09-25 10:36:29 +02:00
}
} else if ( " contentType " . equals ( theName ) ) {
2014-06-03 16:52:21 -04:00
myInstance . setContentType ( theValue ) ;
} else if ( myJsonMode & & " value " . equals ( theName ) ) {
string ( theValue ) ;
}
}
@Override
public void endingElement ( ) throws DataFormatException {
if ( mySubState = = SUBSTATE_CT ) {
myInstance . setContentType ( myData ) ;
mySubState = 0 ;
2014-07-04 09:27:36 -04:00
myData = null ;
2014-06-03 16:52:21 -04:00
return ;
} else if ( mySubState = = SUBSTATE_CONTENT ) {
myInstance . setContentAsBase64 ( myData ) ;
mySubState = 0 ;
2014-07-04 09:27:36 -04:00
myData = null ;
2014-06-03 16:52:21 -04:00
return ;
} else {
if ( ! myJsonMode ) {
2014-07-04 09:27:36 -04:00
myInstance . setContentAsBase64 ( myData ) ;
2014-06-03 16:52:21 -04:00
}
pop ( ) ;
}
}
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
if ( myJsonMode & & " contentType " . equals ( theLocalPart ) & & mySubState = = 0 ) {
mySubState = SUBSTATE_CT ;
} else if ( myJsonMode & & " content " . equals ( theLocalPart ) & & mySubState = = 0 ) {
mySubState = SUBSTATE_CONTENT ;
} else {
throw new DataFormatException ( " Unexpected nested element in atom tag: " + theLocalPart ) ;
}
}
@Override
protected IElement getCurrentElement ( ) {
2014-02-27 16:51:43 -05:00
return null ;
}
2014-06-03 16:52:21 -04:00
@Override
public void string ( String theData ) {
if ( myData = = null ) {
myData = theData ;
} else {
// this shouldn't generally happen so it's ok that it's
// inefficient
myData = myData + theData ;
}
}
2014-02-26 17:13:49 -05:00
}
2014-03-22 12:33:07 -04:00
private class ContainedResourcesState extends PreResourceState {
2014-03-16 15:09:30 -04:00
public ContainedResourcesState ( PreResourceState thePreResourcesState ) {
super ( thePreResourcesState ) ;
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-03-16 15:09:30 -04:00
pop ( ) ;
}
@Override
public void wereBack ( ) {
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 ( ) ) {
2014-03-17 08:57:57 -04:00
ourLog . debug ( " Discarding contained resource with no ID! " ) ;
2014-03-16 15:09:30 -04:00
} else {
getPreResourceState ( ) . getContainedResources ( ) . put ( res . getId ( ) . getValueAsString ( ) , res ) ;
2014-10-15 14:34:14 -04:00
if ( ! res . getId ( ) . isLocal ( ) ) {
res . setId ( new IdDt ( '#' + res . getId ( ) . getIdPart ( ) ) ) ;
}
2014-03-16 15:09:30 -04:00
}
2014-12-10 22:02:31 -05:00
IResource preResCurrentElement = ( IResource ) getPreResourceState ( ) . getCurrentElement ( ) ;
preResCurrentElement . getContained ( ) . getContainedResources ( ) . add ( res ) ;
2014-10-15 14:34:14 -04:00
2014-03-16 15:09:30 -04:00
}
}
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 ;
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-02-26 17:13:49 -05:00
pop ( ) ;
}
@Override
2014-02-27 11:57:50 -05: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 ) {
throw new DataFormatException ( " Unknown extension element name: " + theLocalPart ) ;
}
switch ( target . getChildType ( ) ) {
case COMPOSITE_DATATYPE : {
BaseRuntimeElementCompositeDefinition < ? > compositeTarget = ( BaseRuntimeElementCompositeDefinition < ? > ) target ;
ICompositeDatatype newChildInstance = ( ICompositeDatatype ) compositeTarget . newInstance ( ) ;
myDefinition . getMutator ( ) . addValue ( myParentInstance , newChildInstance ) ;
2014-03-16 15:09:30 -04:00
ElementCompositeState newState = new ElementCompositeState ( myPreResourceState , compositeTarget , newChildInstance ) ;
2014-02-26 17:13:49 -05:00
push ( newState ) ;
return ;
}
case PRIMITIVE_DATATYPE : {
RuntimePrimitiveDatatypeDefinition primitiveTarget = ( RuntimePrimitiveDatatypeDefinition ) target ;
2014-12-10 22:02:31 -05:00
IPrimitiveType < ? > newChildInstance = primitiveTarget . newInstance ( ) ;
2014-02-26 17:13:49 -05:00
myDefinition . getMutator ( ) . addValue ( myParentInstance , newChildInstance ) ;
2014-03-16 15:09:30 -04:00
PrimitiveState newState = new PrimitiveState ( getPreResourceState ( ) , newChildInstance ) ;
2014-02-26 17:13:49 -05:00
push ( newState ) ;
return ;
}
case RESOURCE_REF : {
2014-03-10 18:17:30 -04:00
ResourceReferenceDt newChildInstance = new ResourceReferenceDt ( ) ;
2014-02-26 17:13:49 -05:00
myDefinition . getMutator ( ) . addValue ( myParentInstance , newChildInstance ) ;
2014-06-12 11:42:28 -04:00
ResourceReferenceState newState = new ResourceReferenceState ( getPreResourceState ( ) , newChildInstance ) ;
2014-02-26 17:13:49 -05:00
push ( newState ) ;
return ;
}
case PRIMITIVE_XHTML :
case RESOURCE :
case RESOURCE_BLOCK :
case UNDECL_EXT :
case EXTENSION_DECLARED :
default :
break ;
}
}
@Override
2014-03-10 18:17:30 -04:00
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier ) {
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 {
2014-03-10 18:17:30 -04:00
super . enteringNewElementExtension ( theElement , theUrlAttr , theIsModifier ) ;
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
2014-02-26 17:13:49 -05:00
private class ElementCompositeState extends BaseState {
2014-02-19 11:59:12 -05:00
private BaseRuntimeElementCompositeDefinition < ? > myDefinition ;
2014-12-10 22:02:31 -05:00
private IBase myInstance ;
2014-02-18 08:26:49 -05:00
2014-12-10 22:02:31 -05:00
public ElementCompositeState ( PreResourceState thePreResourceState , 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 ;
}
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 ) ) ;
2014-12-10 22:02:31 -05:00
} else if ( myInstance instanceof Element ) {
( ( Element ) 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 ) ;
2014-03-16 15:09:30 -04:00
}
}
2014-02-27 07:39:36 -05:00
@SuppressWarnings ( " unchecked " )
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 ( ) ;
if ( myState = = null ) {
2014-02-27 07:39:36 -05:00
myObject = ( T ) myInstance ;
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 {
2014-03-28 17:11:56 -04:00
BaseRuntimeChildDefinition child ;
try {
child = myDefinition . getChildByNameOrThrowDataFormatException ( theChildName ) ;
} catch ( DataFormatException e ) {
if ( false ) { // TODO: make this configurable
throw e ;
}
ourLog . warn ( e . getMessage ( ) ) ;
push ( new SwallowChildrenWholeState ( getPreResourceState ( ) ) ) ;
return ;
}
2014-02-19 11:59:12 -05:00
BaseRuntimeElementDefinition < ? > target = child . getChildByName ( theChildName ) ;
2014-02-26 09:03:43 -05:00
if ( target = = null ) {
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 ( ) ) {
case COMPOSITE_DATATYPE : {
BaseRuntimeElementCompositeDefinition < ? > compositeTarget = ( BaseRuntimeElementCompositeDefinition < ? > ) target ;
2014-03-10 18:17:30 -04:00
ICompositeDatatype newChildInstance = ( ICompositeDatatype ) compositeTarget . newInstance ( child . getInstanceConstructorArguments ( ) ) ;
2014-02-19 11:59:12 -05:00
child . getMutator ( ) . addValue ( myInstance , newChildInstance ) ;
2014-03-16 15:09:30 -04:00
ElementCompositeState newState = new ElementCompositeState ( getPreResourceState ( ) , compositeTarget , newChildInstance ) ;
2014-02-19 11:59:12 -05:00
push ( newState ) ;
2014-02-20 12:13:05 -05:00
return ;
2014-02-19 11:59:12 -05:00
}
case PRIMITIVE_DATATYPE : {
RuntimePrimitiveDatatypeDefinition primitiveTarget = ( RuntimePrimitiveDatatypeDefinition ) target ;
2014-12-10 22:02:31 -05:00
IPrimitiveType < ? > newChildInstance ;
2014-03-03 09:05:55 -05:00
newChildInstance = primitiveTarget . newInstance ( child . getInstanceConstructorArguments ( ) ) ;
2014-02-19 11:59:12 -05:00
child . getMutator ( ) . addValue ( myInstance , newChildInstance ) ;
2014-03-16 15:09:30 -04:00
PrimitiveState newState = new PrimitiveState ( getPreResourceState ( ) , newChildInstance ) ;
2014-02-19 11:59:12 -05:00
push ( newState ) ;
2014-02-20 12:13:05 -05:00
return ;
2014-02-19 11:59:12 -05:00
}
2014-02-19 17:33:46 -05:00
case RESOURCE_REF : {
RuntimeResourceReferenceDefinition resourceRefTarget = ( RuntimeResourceReferenceDefinition ) target ;
2014-03-10 18:17:30 -04:00
ResourceReferenceDt newChildInstance = new ResourceReferenceDt ( ) ;
2014-03-16 15:09:30 -04:00
getPreResourceState ( ) . getResourceReferences ( ) . add ( newChildInstance ) ;
2014-02-19 17:33:46 -05:00
child . getMutator ( ) . addValue ( myInstance , newChildInstance ) ;
2014-06-12 11:42:28 -04:00
ResourceReferenceState newState = new ResourceReferenceState ( getPreResourceState ( ) , newChildInstance ) ;
2014-02-19 17:33:46 -05:00
push ( newState ) ;
2014-02-20 12:13:05 -05:00
return ;
}
case RESOURCE_BLOCK : {
RuntimeResourceBlockDefinition blockTarget = ( RuntimeResourceBlockDefinition ) target ;
IResourceBlock newBlockInstance = blockTarget . newInstance ( ) ;
child . getMutator ( ) . addValue ( myInstance , newBlockInstance ) ;
2014-03-16 15:09:30 -04:00
ElementCompositeState newState = new ElementCompositeState ( getPreResourceState ( ) , blockTarget , newBlockInstance ) ;
2014-02-20 12:13:05 -05:00
push ( newState ) ;
return ;
2014-02-19 11:59:12 -05:00
}
2014-02-22 15:33:02 -05:00
case PRIMITIVE_XHTML : {
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = ( RuntimePrimitiveDatatypeNarrativeDefinition ) target ;
XhtmlDt newDt = xhtmlTarget . newInstance ( ) ;
child . getMutator ( ) . addValue ( myInstance , newDt ) ;
2014-03-16 15:09:30 -04:00
XhtmlState state = new XhtmlState ( getPreResourceState ( ) , newDt , true ) ;
2014-02-22 15:33:02 -05:00
push ( state ) ;
return ;
}
2014-03-17 08:57:57 -04:00
case CONTAINED_RESOURCES : {
RuntimeElemContainedResources targetElem = ( RuntimeElemContainedResources ) target ;
2014-12-10 22:02:31 -05:00
List < ? extends IBase > values = child . getAccessor ( ) . getValues ( myInstance ) ;
2014-03-22 12:33:07 -04:00
ContainedDt newDt ;
if ( values = = null | | values . isEmpty ( ) | | values . get ( 0 ) = = null ) {
newDt = targetElem . newInstance ( ) ;
child . getMutator ( ) . addValue ( myInstance , newDt ) ;
2014-04-14 08:40:30 -04:00
} else {
2014-03-22 12:33:07 -04:00
newDt = ( ContainedDt ) values . get ( 0 ) ;
}
2014-03-17 08:57:57 -04:00
ContainedResourcesState state = new ContainedResourcesState ( getPreResourceState ( ) ) ;
push ( state ) ;
return ;
}
2014-02-22 15:33:02 -05:00
case UNDECL_EXT :
2014-07-04 09:27:36 -04:00
case RESOURCE :
case EXTENSION_DECLARED : {
2014-02-20 12:13:05 -05:00
// Throw an exception because this shouldn't happen here
break ;
2014-02-19 11:59:12 -05:00
}
2014-02-22 15:33:02 -05:00
}
throw new DataFormatException ( " Illegal resource position: " + target . getChildType ( ) ) ;
}
@Override
2014-03-10 18:17:30 -04:00
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier ) {
2014-02-26 17:13:49 -05:00
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition . getDeclaredExtension ( theUrlAttr ) ;
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 {
2014-03-10 18:17:30 -04:00
super . enteringNewElementExtension ( theElement , theUrlAttr , theIsModifier ) ;
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
2014-12-10 22:02:31 -05:00
protected IBase getCurrentElement ( ) {
2014-02-22 15:33:02 -05:00
return myInstance ;
}
}
private class ExtensionState extends BaseState {
2014-03-27 08:51:02 -04:00
private ExtensionDt myExtension ;
2014-02-22 15:33:02 -05:00
2014-03-27 08:51:02 -04:00
public ExtensionState ( PreResourceState thePreResourceState , ExtensionDt theExtension ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourceState ) ;
2014-02-22 15:33:02 -05:00
myExtension = theExtension ;
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-02-22 15:33:02 -05:00
if ( myExtension . getValue ( ) ! = null & & myExtension . getUndeclaredExtensions ( ) . size ( ) > 0 ) {
throw new DataFormatException ( " Extension 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
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-02-22 15:33:02 -05:00
BaseRuntimeElementDefinition < ? > target = myContext . getRuntimeChildUndeclaredExtensionDefinition ( ) . getChildByName ( theLocalPart ) ;
if ( target = = null ) {
throw new DataFormatException ( " Unknown extension element name: " + theLocalPart ) ;
2014-02-21 21:06:11 -05:00
}
2014-02-22 15:33:02 -05:00
switch ( target . getChildType ( ) ) {
case COMPOSITE_DATATYPE : {
BaseRuntimeElementCompositeDefinition < ? > compositeTarget = ( BaseRuntimeElementCompositeDefinition < ? > ) target ;
ICompositeDatatype newChildInstance = ( ICompositeDatatype ) compositeTarget . newInstance ( ) ;
myExtension . setValue ( newChildInstance ) ;
2014-03-16 15:09:30 -04:00
ElementCompositeState newState = new ElementCompositeState ( getPreResourceState ( ) , compositeTarget , newChildInstance ) ;
2014-02-22 15:33:02 -05:00
push ( newState ) ;
return ;
}
case PRIMITIVE_DATATYPE : {
RuntimePrimitiveDatatypeDefinition primitiveTarget = ( RuntimePrimitiveDatatypeDefinition ) target ;
2014-12-10 22:02:31 -05:00
IPrimitiveType < ? > newChildInstance = primitiveTarget . newInstance ( ) ;
myExtension . setValue ( ( IElement ) newChildInstance ) ;
2014-03-16 15:09:30 -04:00
PrimitiveState newState = new PrimitiveState ( getPreResourceState ( ) , newChildInstance ) ;
2014-02-22 15:33:02 -05:00
push ( newState ) ;
return ;
}
case RESOURCE_REF : {
2014-03-10 18:17:30 -04:00
ResourceReferenceDt newChildInstance = new ResourceReferenceDt ( ) ;
2014-02-22 15:33:02 -05:00
myExtension . setValue ( newChildInstance ) ;
2014-06-12 11:42:28 -04:00
ResourceReferenceState newState = new ResourceReferenceState ( getPreResourceState ( ) , newChildInstance ) ;
2014-02-22 15:33:02 -05:00
push ( newState ) ;
return ;
}
case PRIMITIVE_XHTML :
case RESOURCE :
case RESOURCE_BLOCK :
case UNDECL_EXT :
2014-06-03 16:52:21 -04:00
case EXTENSION_DECLARED :
case CONTAINED_RESOURCES :
2014-02-22 15:33:02 -05:00
break ;
}
}
2014-02-26 17:13:49 -05:00
@Override
protected IElement getCurrentElement ( ) {
return myExtension ;
}
}
2014-02-27 16:51:43 -05:00
private class PreAtomState extends BaseState {
private Bundle myInstance ;
2014-12-10 17:40:47 -05:00
private Class < ? extends IBaseResource > myResourceType ;
2014-02-26 17:13:49 -05:00
2014-12-10 17:40:47 -05:00
public PreAtomState ( Class < ? extends IBaseResource > theResourceType ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-04-30 18:39:33 -04:00
myResourceType = theResourceType ;
2014-03-16 15:09:30 -04:00
}
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
// ignore
}
2014-02-27 16:51:43 -05:00
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
if ( ! " feed " . equals ( theLocalPart ) ) {
throw new DataFormatException ( " Expecting outer element called 'feed', found: " + theLocalPart ) ;
}
myInstance = new Bundle ( ) ;
2014-04-30 18:39:33 -04:00
push ( new AtomState ( myInstance , myResourceType ) ) ;
2014-02-27 16:51:43 -05:00
}
@Override
2014-06-03 16:52:21 -04:00
protected IElement getCurrentElement ( ) {
return myInstance ;
2014-02-27 16:51:43 -05:00
}
2014-06-03 16:52:21 -04:00
@SuppressWarnings ( " unchecked " )
2014-02-27 16:51:43 -05:00
@Override
2014-06-03 16:52:21 -04:00
public void wereBack ( ) {
myObject = ( T ) myInstance ;
2014-08-15 09:19:07 -04:00
2014-08-05 17:06:35 -04:00
/ *
* Stitch together resource references
* /
2014-08-15 09:19:07 -04:00
2014-12-10 22:02:31 -05:00
Map < String , IResource > idToResource = new HashMap < String , IResource > ( ) ;
List < IResource > resources = myInstance . toListOfResources ( ) ;
for ( IResource next : resources ) {
2014-08-15 09:19:07 -04:00
if ( next . getId ( ) ! = null & & next . getId ( ) . isEmpty ( ) = = false ) {
2014-08-05 17:06:35 -04:00
idToResource . put ( next . getId ( ) . toUnqualifiedVersionless ( ) . getValue ( ) , next ) ;
}
}
2014-08-15 09:19:07 -04:00
2014-12-10 17:40:47 -05:00
for ( IBaseResource next : resources ) {
2014-08-05 17:06:35 -04:00
List < ResourceReferenceDt > refs = myContext . newTerser ( ) . getAllPopulatedChildElementsOfType ( next , ResourceReferenceDt . class ) ;
for ( ResourceReferenceDt nextRef : refs ) {
2014-08-15 09:19:07 -04:00
if ( nextRef . isEmpty ( ) = = false & & nextRef . getReference ( ) ! = null ) {
2014-12-10 22:02:31 -05:00
IResource target = idToResource . get ( nextRef . getReference ( ) . getValue ( ) ) ;
2014-08-05 17:06:35 -04:00
if ( target ! = null ) {
nextRef . setResource ( target ) ;
}
}
}
}
2014-08-15 09:19:07 -04:00
2014-02-27 16:51:43 -05:00
}
}
2014-03-22 12:33:07 -04:00
2014-02-27 16:51:43 -05:00
private class PreResourceState extends BaseState {
2014-12-10 17:40:47 -05:00
private Map < String , IBaseResource > myContainedResources = new HashMap < String , IBaseResource > ( ) ;
2014-02-27 16:51:43 -05:00
private BundleEntry myEntry ;
2014-12-10 22:02:31 -05:00
private IResource myInstance ;
2014-03-16 15:09:30 -04:00
private List < ResourceReferenceDt > myResourceReferences = new ArrayList < ResourceReferenceDt > ( ) ;
2014-12-10 17:40:47 -05:00
private Class < ? extends IBaseResource > myResourceType ;
2014-02-27 16:51:43 -05:00
2014-12-10 17:40:47 -05:00
public PreResourceState ( BundleEntry theEntry , Class < ? extends IBaseResource > theResourceType ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
myEntry = theEntry ;
2014-05-05 05:57:43 -07:00
myResourceType = theResourceType ;
2014-03-16 15:09:30 -04:00
}
2014-03-07 16:23:49 -05:00
/ * *
* @param theResourceType
* May be null
* /
2014-12-10 17:40:47 -05:00
public PreResourceState ( Class < ? extends IBaseResource > theResourceType ) {
2014-03-16 15:09:30 -04:00
super ( null ) ;
2014-03-07 16:23:49 -05:00
myResourceType = theResourceType ;
2014-02-27 16:51:43 -05:00
}
2014-03-16 15:09:30 -04:00
public PreResourceState ( PreResourceState thePreResourcesState ) {
super ( thePreResourcesState ) ;
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 {
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
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-03-07 16:23:49 -05:00
BaseRuntimeElementDefinition < ? > definition ;
if ( myResourceType = = null ) {
definition = myContext . getResourceDefinition ( theLocalPart ) ;
2014-08-27 08:55:00 -04:00
if ( ( definition = = null ) ) {
2014-03-07 16:23:49 -05:00
throw new DataFormatException ( " Element ' " + theLocalPart + " ' is not a resource, expected a resource at this position " ) ;
}
} else {
definition = myContext . getResourceDefinition ( myResourceType ) ;
if ( ! StringUtils . equals ( theLocalPart , definition . getName ( ) ) ) {
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 ;
2014-12-10 22:02:31 -05:00
myInstance = ( IResource ) def . newInstance ( ) ;
2014-02-27 16:51:43 -05:00
if ( myEntry ! = null ) {
myEntry . setResource ( myInstance ) ;
}
2014-02-26 17:13:49 -05:00
2014-05-28 07:30:40 -04:00
if ( " Binary " . equals ( def . getName ( ) ) ) {
2014-06-03 16:52:21 -04:00
push ( new BinaryResourceState ( getRootPreResourceState ( ) , ( Binary ) myInstance ) ) ;
2014-05-28 07:30:40 -04:00
} else {
2014-06-03 16:52:21 -04:00
push ( new ElementCompositeState ( getRootPreResourceState ( ) , def , myInstance ) ) ;
2014-05-28 07:30:40 -04:00
}
2014-03-16 15:09:30 -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 ;
}
2014-03-16 15:09:30 -04:00
public List < ResourceReferenceDt > getResourceReferences ( ) {
return myResourceReferences ;
2014-02-26 17:13:49 -05:00
}
2014-06-03 16:52:21 -04:00
private PreResourceState getRootPreResourceState ( ) {
if ( getPreResourceState ( ) ! = null ) {
return getPreResourceState ( ) ;
2014-07-04 09:27:36 -04:00
} else {
2014-06-03 16:52:21 -04:00
return this ;
}
}
2014-05-05 05:57:43 -07:00
@Override
public boolean isPreResource ( ) {
return true ;
}
2014-02-27 16:51:43 -05:00
@SuppressWarnings ( " unchecked " )
2014-02-22 15:33:02 -05:00
@Override
2014-02-27 16:51:43 -05:00
public void wereBack ( ) {
if ( myEntry = = null ) {
myObject = ( T ) myInstance ;
}
2014-03-22 12:33:07 -04:00
2014-08-19 07:48:06 -04:00
myContext . newTerser ( ) . visit ( myInstance , new IModelVisitor ( ) {
2014-08-27 08:55:00 -04:00
2014-08-19 07:48:06 -04:00
@Override
2014-09-30 11:57:15 -04:00
public void acceptUndeclaredExtension ( ISupportsUndeclaredExtensions theContainingElement , BaseRuntimeChildDefinition theChildDefinition , BaseRuntimeElementDefinition < ? > theDefinition ,
ExtensionDt theNextExt ) {
2014-08-19 07:48:06 -04:00
acceptElement ( theNextExt . getValue ( ) , null , null ) ;
}
2014-08-27 08:55:00 -04:00
2014-08-19 07:48:06 -04:00
@Override
2014-12-10 22:02:31 -05:00
public void acceptElement ( IBase theElement , BaseRuntimeChildDefinition theChildDefinition , BaseRuntimeElementDefinition < ? > theDefinition ) {
2014-08-19 07:48:06 -04:00
if ( theElement instanceof ResourceReferenceDt ) {
2014-08-27 08:55:00 -04:00
ResourceReferenceDt nextRef = ( ResourceReferenceDt ) theElement ;
2014-08-19 07:48:06 -04:00
String ref = nextRef . getReference ( ) . getValue ( ) ;
if ( isNotBlank ( ref ) ) {
if ( ref . startsWith ( " # " ) ) {
2014-12-10 22:02:31 -05:00
IResource target = ( IResource ) myContainedResources . get ( ref . substring ( 1 ) ) ;
2014-08-19 07:48:06 -04:00
if ( target ! = null ) {
nextRef . setResource ( target ) ;
} else {
ourLog . warn ( " Resource contains unknown local ref: " + ref ) ;
}
}
2014-03-16 15:09:30 -04:00
}
}
}
2014-08-19 07:48:06 -04:00
} ) ;
2014-08-27 08:55:00 -04:00
2014-02-26 17:13:49 -05:00
}
2014-02-18 08:26:49 -05:00
}
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
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
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
protected TagList getCurrentElement ( ) {
return myTagList ;
}
2014-05-07 08:18:43 -04:00
@Override
public boolean isPreResource ( ) {
return true ;
}
@SuppressWarnings ( " unchecked " )
@Override
public void wereBack ( ) {
myObject = ( T ) myTagList ;
}
}
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 ) ) {
myInstance . setValueAsString ( theValue ) ;
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 ) ;
2014-12-10 22:02:31 -05:00
} else if ( myInstance instanceof Element ) {
( ( Element ) 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 ( ( org . hl7 . fhir . instance . model . IBaseResource ) myInstance ) ;
2014-07-04 09:27:36 -04:00
}
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
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-03-22 12:33:07 -04:00
throw new Error ( " Element " + theLocalPart + " in primitive! " ) ; // TODO:
// can
// this
// happen?
2014-02-19 11:59:12 -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
}
2014-02-21 21:06:11 -05:00
private class ResourceReferenceState extends BaseState {
2014-03-10 18:17:30 -04:00
private ResourceReferenceDt myInstance ;
2014-02-21 21:06:11 -05:00
private ResourceReferenceSubState mySubState ;
2014-06-12 11:42:28 -04:00
public ResourceReferenceState ( PreResourceState thePreResourceState , ResourceReferenceDt theInstance ) {
2014-03-16 15:09:30 -04:00
super ( thePreResourceState ) ;
2014-02-21 21:06:11 -05:00
myInstance = theInstance ;
mySubState = ResourceReferenceSubState . INITIAL ;
}
@Override
2014-02-27 16:51:43 -05:00
public void attributeValue ( String theName , String theValue ) throws DataFormatException {
if ( ! " value " . equals ( theName ) ) {
return ;
}
2014-03-06 17:12:05 -05:00
2014-02-21 21:06:11 -05:00
switch ( mySubState ) {
case DISPLAY :
myInstance . setDisplay ( theValue ) ;
break ;
case INITIAL :
throw new DataFormatException ( " Unexpected attribute: " + theValue ) ;
case REFERENCE :
myInstance . setReference ( theValue ) ;
break ;
}
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) {
2014-02-21 21:06:11 -05:00
switch ( mySubState ) {
case INITIAL :
pop ( ) ;
break ;
case DISPLAY :
case REFERENCE :
mySubState = ResourceReferenceSubState . INITIAL ;
}
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
2014-02-21 21:06:11 -05:00
switch ( mySubState ) {
case INITIAL :
if ( " display " . equals ( theLocalPart ) ) {
mySubState = ResourceReferenceSubState . DISPLAY ;
break ;
} else if ( " reference " . equals ( theLocalPart ) ) {
mySubState = ResourceReferenceSubState . REFERENCE ;
break ;
2014-03-22 12:33:07 -04:00
} else if ( " resource " . equals ( theLocalPart ) ) {
mySubState = ResourceReferenceSubState . REFERENCE ;
break ;
2014-02-21 21:06:11 -05:00
}
//$FALL-THROUGH$
case DISPLAY :
case REFERENCE :
throw new DataFormatException ( " Unexpected element: " + theLocalPart ) ;
}
}
2014-02-22 15:33:02 -05:00
@Override
2014-02-26 17:13:49 -05:00
protected IElement getCurrentElement ( ) {
return myInstance ;
2014-02-22 15:33:02 -05:00
}
2014-02-18 08:26:49 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-21 21:06:11 -05:00
private enum ResourceReferenceSubState {
DISPLAY , INITIAL , REFERENCE
2014-02-19 11:59:12 -05:00
}
2014-05-05 05:57:43 -07:00
private class SwallowChildrenWholeState extends BaseState {
private int myDepth ;
public SwallowChildrenWholeState ( PreResourceState thePreResourceState ) {
super ( thePreResourceState ) ;
}
@Override
public void endingElement ( ) throws DataFormatException {
myDepth - - ;
if ( myDepth < 0 ) {
pop ( ) ;
}
}
2014-10-24 15:43:35 -04:00
@Override
public void enteringNewElementExtension ( StartElement theElement , String theUrlAttr , boolean theIsModifier ) {
myDepth + + ;
}
2014-05-05 05:57:43 -07:00
@Override
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
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
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
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 ) ;
}
}
}
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 ;
private int mySubState = 0 ;
2014-09-30 11:57:15 -04:00
private TagList myTagList ;
private String myTerm ;
private String myLabel ;
private String myScheme ;
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 ) {
case TERM :
2014-09-30 11:57:15 -04:00
myTerm = ( value ) ;
2014-05-07 08:18:43 -04:00
break ;
case LABEL :
2014-09-30 11:57:15 -04:00
myLabel = ( value ) ;
2014-05-07 08:18:43 -04:00
break ;
case SCHEME :
2014-09-30 11:57:15 -04:00
myScheme = ( value ) ;
2014-05-07 08:18:43 -04:00
break ;
case NONE :
// This handles JSON encoding, which is a bit weird
enteringNewElement ( null , theName ) ;
attributeValue ( null , value ) ;
endingElement ( ) ;
break ;
}
}
@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
public void enteringNewElement ( String theNamespaceURI , String theLocalPart ) throws DataFormatException {
if ( Tag . ATTR_TERM . equals ( theLocalPart ) ) {
mySubState = TERM ;
} else if ( Tag . ATTR_SCHEME . equals ( theLocalPart ) ) {
mySubState = SCHEME ;
} else if ( Tag . ATTR_LABEL . equals ( theLocalPart ) ) {
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 ) ;
return ;
}
super . attributeValue ( theName , theValue ) ;
}
@Override
2014-03-24 08:32:28 -04:00
public void endingElement ( ) throws DataFormatException {
2014-03-22 12:33:07 -04:00
if ( myJsonMode ) {
pop ( ) ;
return ;
}
2014-03-24 08:32:28 -04:00
super . endingElement ( ) ;
2014-03-22 12:33:07 -04:00
}
2014-06-03 16:52:21 -04:00
@Override
protected IElement getCurrentElement ( ) {
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 ) {
myDt . setValue ( myEvents ) ;
pop ( ) ;
}
2014-02-21 21:06:11 -05:00
}
}
2014-02-19 11:59:12 -05:00
}
2014-02-18 08:26:49 -05:00
}