Search code examples
javaparsingversionclasscastexceptionhapi

HAPI - Custom model class that is also canonical?


I have an application that currently uses a custom model with custom message types and Z segment classes. For example, i have a DFT_P03 class in my v25 package that extends AbstractMessage and declares segments, also in the same package, as such :

private void init(ModelClassFactory factory) 
{
    try 
    {
        this.add(MSH.class, true, false);
        this.add(PID.class, false, false);
        this.add(PV1.class, false, false);
        this.add(FT1.class, false, false);
        this.add(ZPM.class, false, false);
    } 
    catch (HL7Exception e) 
    {}
}

This is how i create my HapiContext, which points to this same package :

public void initializeHAPI()
{
    try
    {
        ModelClassFactory cmf = new CustomModelClassFactory("com.somepackage.somelibraryname.hl7.custommodel");

        MinLowerLayerProtocol mllp = new MinLowerLayerProtocol();
        mllp.setCharset(StandardCharsets.ISO_8859_1.name());

        hapiContext = new DefaultHapiContext();
        hapiContext.setValidationContext(ValidationContextFactory.noValidation());
        hapiContext.getPipeParser().getParserConfiguration().setUnexpectedSegmentBehaviour(UnexpectedSegmentBehaviourEnum.ADD_INLINE);
        hapiContext.setModelClassFactory(cmf);
        hapiContext.setLowerLayerProtocol(mllp);

        logEntryService.logInfo(LogEntrySource.SERVICE, LogEntryType.CORE, "Successfully initialized HAPI framework", logger);
    }
    catch (Exception ex)
    {
        logEntryService.logError(LogEntrySource.SERVICE, LogEntryType.CORE, "Error initializing HAPI framework : " 
            + ex.getMessage(), logger);
    }
}

As long as i send messages with 2.5 in MSH.12, everything works flawlessly. I would like to integrate CanonicalModelClassFactory into this so it can parse lower versions as v2.5 messages without throwing a ClassCastException when i try to parse the message to my v2.5 DFT_P03 class. I have read all the info I could find about this and unfortunately none of it used it in conjunction with a CustomModelClassFactory.

I actually created my own CustomModelClassFactory class that extends CanonicalClassModelFactory and modified the constructor chain as such :

public CustomModelClassFactory() 
{
    this((Map<String, String[]>)null);
}

public CustomModelClassFactory(String packageName) 
{
    this(new HashMap<String, String[]>());

    if (!packageName.endsWith(".")) 
    {
        packageName += ".";
    }
    for (Version v : Version.values()) 
    {
        addModel(v.getVersion(), new String[] {packageName + v.getPackageVersion()});
    }
}

public CustomModelClassFactory(Map<String, String[]> map) 
{
    this(new CanonicalModelClassFactory("2.5"), map);
}

public CustomModelClassFactory(ModelClassFactory defaultFactory, Map<String, String[]> map) 
{
    super("2.5");

    this.delegate = defaultFactory;
    customModelClasses = map;
}    

Note the delegate model being set to a CanonicalModelClassFactory and the super("2.5") call. Sadly this still throws a ClassCastException when trying to parse anything else then a v2.5 DFT message.

Any ideas on how to integrate these 2 behaviors together?

Thanks!


Solution

  • we found a way to combine those two behaviors.

    public class CustomModelCanonicalClassFactory extends CustomModelClassFactory {
    private String customVersion;
    
       public CustomModelCanonicalClassFactory(String packageName, String version){
            super(packageName);
            if (version == null || !Version.supportsVersion(version)) {
                throw new IllegalArgumentException("Unknown version: " + version);
            }
            this.customVersion = version;
        }
    
    }
    

    then override all methods you need, give the explicit version to the super#method

    
        @Override
        public Class<? extends Message> getMessageClass(String name, String version, boolean isExplicit) throws HL7Exception {
            return super.getMessageClass(name, this.customVersion, isExplicit);
        }
    
        @Override
        public Class<? extends Group> getGroupClass(String name, String version) throws HL7Exception {
            return super.getGroupClass(name, this.customVersion);
        }
    

    Best regards, Patrick