views:

25

answers:

1

I'm currently refactoring a library for internal use in Java.

The library receives an XML document, and returns a Result data structure. Given that:

  • There are two clients for this library, one has the XML document as an InputStream and the other has a file path as a String.
  • The class that the clients use is passing around inside the library before being actually processed

what it the best architecture for handling the file?

Currently, it is handled in the following way (unrelated details omitted, classes' names changed):

public class ILuvUsers {

public Result getResult(String path) {
    return getResult(ElementsLoader.loadIntermediateType(path));
}

public Result getResult(InputStream stream) {
    return getResult(ElementsLoader.loadIntermediateType(stream));
}

private Result getResult(IntermediateType itype) {
    //... do stuff and return Result
}
}

public class ElementsLoader {
public static IntermediateType loadIntermediateType(final InputStream is) {
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
    return doSomethingWithDocument(doc);
}

public static IntermediateType loadIntermediateType(final String path) {
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(path);
    return doSomethingWithDocument(doc);
}
}

The way I need to create overloads in each class for InputStream and a String seems like a code smell to me. What if the next day I'll need to support using the 'File' type? Optimally I would like to somehow automagically support every overload for the DocumentBuilder's parse methods.

Since this is not really possible in Java and it all seems like a common enough case, what are the best practices for this problem? Have you seen any good solutions?

+1  A: 

This is not really all that bad. The domain is limited and doesn't grow quickly.

However, you've spotted an issue where you need to find a "lowest common denominator" for inputs.

That's usually some kind of InputStream.

Given a String, you want to open a Stream and use the Stream Loader.

Given a Stream, you're golden.

Given a File, you'll want to open a Stream and use the Stream Loader.

This should cover just about all possible bases, since AFAIK you can make an InputStream out of almost anything.

S.Lott
In the end I did what you suggested and used InputStream only.If the user wants to use a path/File then he can use FileInputStream.
maayank