tags:

views:

72

answers:

2

I've got the following JAXB unmarshalling code which I'm trying to generalize. Here's what it looks like:

private Object getResponseObject(String stubbedXmlFile, 
        Class jaxbInterfaceClass,
        AbstractRepository repository) {
    Object responseObject = null;
    try {
        JAXBContext jc = JAXBContext.newInstance(jaxbInterfaceClass);
        Unmarshaller u = jc.createUnmarshaller();
        InputStream resourceAsStream = TestProvidePensionValuationRepository.class.getClassLoader()
                .getResourceAsStream(stubbedXmlFile);
        BufferedReader br = new BufferedReader(new InputStreamReader(resourceAsStream));
        StringBuilder sb = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            sb.append(line);
        }
        br.close();
        ByteArrayInputStream byteStream = 
               new ByteArrayInputStream(sb.toString().getBytes());
        responseObject = u.unmarshal(byteStream);
    } catch (JAXBException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return responseObject;
}

My goal is not to return an Object, but the same class which is passed in as a parameter (e.g. the jaxbInterfaceClass). I'm thinking this might be possible with Generics, but as a relative newbie to generics I'm stumped. Any help appreciated!

+7  A: 

This isn't really a JAXB issue at all, just some tweaking of the generics required:

private <T> T getResponseObject(String stubbedXmlFile, 
                                Class<T> jaxbInterfaceClass, 
                                AbstractRepository repository) {
    T responseObject = null;
    // code as before
    responseObject = (T) u.unmarshal(byteStream);

    return responseObject;
}

This will likely raise a compiler warning, but that's not uncommon with code that bridges generics code with non-generics code like JAXB.

You can then call this with:

MyType x = getResponseObject(file, MyType.class, repo);
skaffman
Yep, I knew it wasn't a JAXB issue. Thanks for your reponse, it was just the kind of code I knew I had seen before, but couldn't remember how to implement. Ta. p.s. can the letter ``T`` be anything you like?
Chris Knight
@Chris: Yes, `T` is just a naming convention. I recommend sticking to it, though.
skaffman
@Chris just expanding on skaffman's comment: the convention is to use single letters like `T` to distinguish generic type parameters from class names and variables. e.g. you could call it `ClassToUnmarshal` but that would be confusing.
mikej
A: 

You can make @skaffman's code type-safe with:

responseObject = jaxbInterfaceClass.cast(u.unmarshal(byteStream));

note, however, that you should probably deal with JAXBElement...

james