I'm trying to build a service in OSGi that would read files of a given format.
The service interface looks like this:
public interface FileReaderService {
/**
* Reads the given file.
* @param filePath Path of the file to read
* @return the data object built from the file
* @throws IOException if there is an error while reading the file
*/
Data readFile(Path filePath) throws IOException;
/**
* Detects if the format of the provided file is supported.
* @param filePath the file to check
* @return true if the format of the file is supported, false otherwise
* @throws IOException if there is an error while reading the file
*/
boolean isFormatSupported(Path filePath) throws IOException;
}
The Data object is a class that defines the data structure of the files to read (they are supposed to contain the same kind of data).
The idea is to have different service implementations, such as:
public class TxtFileReader implements FileReaderService {
@Override
public Data readFile(Path filePath) throws IOException {
// Do something smart with the file
return data;
}
}
@Override
public boolean isFormatSupported(Path filePath) throws IOException {
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:*.txt");
return matcher.matches(filePath);
}
}
There could also be other implementations, such as XmlFileReader, MdFileReader, etc.
Finally, I want a FileReaderFactory like this:
@Component
public class FileReaderFactory implements FileReaderService {
private List<FileReaderService> availableServices = new ArrayList<>();
@Override
public Data readFile(Path filePath) throws IOException {
for (FileReaderService reader : availableServices) {
if (reader.isFormatSupported(filePath)) {
return reader.readFile(filePath);
}
}
return null;
}
@Override
public boolean isFormatSupported(Path filePath) throws IOException {
for (FileReaderService reader : availableServices) {
if (reader.isFormatSupported(filePath)) {
return true;
}
}
return false;
}
}
What I would like is DS to inject the FileReaderServices in the factory list dynamically. Depending on how many services are provided, I would support (or not) a given file format.
My questions are thus:
1) Is this feasible with DS?
2) If yes, how to do it with DS annotations?
3) If not, how would you do it?
Thanks
Edit: I tried Christian's solution, but it didn't work (yet). Full code can be downloaded here: https://github.com/neopium/FileReader