I have a Factory
that instantiates the PARSER
responsible for extracting information from a particular invoice format. To determine the invoice format I use regex. I loop every regex added to Map
and check if the regex is found inside the text of that invoice, if found, then instantiate the PARSER
responsible for extracting the data from that invoice.
For this, I created a Map
of Class and String, where String is the regex. It was necessary to use Class because I can not instantiate this PARSER
before knowing if it really is itself that it will be PARSER
responsible because there are some logics in the constructor of each PARSER
.
public class InvoiceParserFactory
{
private static final Logger logger = LoggerFactory.getLogger(InvoiceParserFactory.class);
private static Map<Class<? extends InvoiceParser>, String> map = new HashMap<>();
static {
map.put(xxx_PARSER.class, "regex_xxx");
map.put(yyy_PARSER.class, "regex_yyy");
map.put(zzz_PARSER.class, "regex_zzz");
//...
}
public static InvoiceParser getParser(InvoicePdfReader reader)
{
String invoiceText = reader.getText();
for (Map.Entry<Class<? extends InvoiceParser>, String> entry : map.entrySet()) {
Class<?> clazz = entry.getKey();
String regex = entry.getValue();
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(invoiceText);
if (m.find()) {
try {
Constructor<?> constructor = clazz.getConstructor(String.class);
return (InvoiceParser) constructor.newInstance(invoiceText);
} catch (Exception e) {
logger.error("Can't instantiate parser.", e);
}
}
}
throw new InvoiceException("Can't find parser.");
}
}
Doubt
Is this the best practice for this purpose? Particularly I found a gambiarra. Any suggestions to improve / refactor the code? Maybe using Java 8 features?
Problem
In the future, I will need to regex, to perform some other condition, so I would have to completely refactor this Factory to support that in addition to a regex, it is possible to use other logic to instantiate the correct PARSER
or something similar. What is the best practice in this case?