Question

I'm trying to solve the following inheritance problem. I have a webservice with several classes that can be accessed trough an URI: for example the URI:

http://localhost:8080/WebApp/data/someData/1

Returns an HTTP GET-Request as application/xml that looks like:

<someData>
    <name>Very Important Data</name>
    <id>2</id>
    <description>Second Test Data</description>
</someData>

Inside my SomeData class I have a static method that casts the URI given above into a SomeData object. The method looks like this:

public static SomeData create(URI resourceUri) {

    ClientConfig clientConfig = new DefaultClientConfig();
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    Client client = Client.create(clientConfig);
    WebResource webResource = client.resource(resourceUri);

    SomeData someData = webResource.accept(MediaType.APPLICATION_XML).get(SomeData.class);

    return someData;        
}

This works so far. However I have several of this data classes and I don't want to write this method every time I create a new data object. Because for my understanding the method would be for all objects the same except for the one line where only the return type and the class description differ from object to object:

SomeData someData = webResource.accept(mediaType).get(SomeData.class);

Now my initial idea was that I create an inheritance tree where the root class (i.e. the parent) has a method like the create methods stated above. So is their a way to implement this method only once and use it for all classes that inherit from the base class? My gut feeling tells me that this doesn't work but I could be wrong.

Maybe a better solution would be to create a static factory method that has a Class parameter that creates objects. Something like this:

public class SomeDataFactory {

    public static SomeDataParent create(URI resourceUri, Class<? extends SomeDataParent> clazz) {

        ClientConfig clientConfig = new DefaultClientConfig();
        clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
        Client client = Client.create(clientConfig);
        WebResource webResource = client.resource(resourceUri);

        SomeDataParent someData = webResource.accept(MediaType.APPLICATION_XML).get(clazz);

        return someData;        
    }
}

Which I would call like this:

SomeData someData = (SomeData) SomeDataFactory.create(new URI(http://localhost:8080/WebApp/data/someData/1), SomeData);

Would this be a viable (e.g. good and working) solution for only implementing this once? I still need inheritance between objects that have nothing in common besides that they can be created from an URI.

With that approach I don't like that you have to add a cast to the creation method. I mean it should be clear what this method creates because I pass the class of the object I want to be created.

Any input is appreciated.

Greetings

Was it helpful?

Solution

Actually, your code could be improved in such a way, that you would not need inheritance for unrelated entities (which is really bad design decision) and any casts. Solution for this - generics. First I looked at JavaDoc for WebResource.Builder#get method. It gave me a clue and I came up with the following code which compiles without any warnings and does not contain casts:

public static <T> T create(URI resourceUri, Class<T> clazz) {

    ClientConfig clientConfig = new DefaultClientConfig();
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    Client client = Client.create(clientConfig);
    WebResource webResource = client.resource(resourceUri);

    T someData = webResource.accept(MediaType.APPLICATION_XML).get(clazz);

    return someData;        
}

So the call to the method above will be like this:

SomeData someData = SomeDataFactory.create(yourUri, SomeData.class);

or

SomeOtherData someOtherData = SomeDataFactory.create(yourUri, SomeOtherData.class);

Good luck!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top