net.glxn.qrgen.core.scheme.ExtendableQRCodeSchemeParser Maven / Gradle / Ivy
package net.glxn.qrgen.core.scheme;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedHashSet;
import java.util.Properties;
import java.util.Set;
/**
* An implementation of {@link QRCodeSchemeParser} which supports the types
* {@link Wifi}, {@link VCard}, {@link Girocode} and {@link URL}, and may be
* extended by additional parsers for custom types.
*
* In order to add a parser, you have to put a properties file named
* qrcode.meta
into your META-INF
folder, containing a
* comma-separated list of your parser class names assigned to the key
* net.glxn.qrgen.core.scheme.QRCodeSchemeParser
. Let's say you
* have additional parsers with the full qualified names
* org.me.FooSchemeParser
and org.me.BarSchemeParser
,
* your qrcode.meta must have the following entry.
*
*
* META-INF/qrcode.meta:
*
*
* net.glxn.qrgen.core.scheme.QRCodeSchemeParser=\
* org.me.FooSchemeParser,\
* org.me.BarSchemeParser
*
*
* TODO: does this parser stuff make sense at all?
*/
public class ExtendableQRCodeSchemeParser implements QRCodeSchemeParser {
private Set parser;
@Override
public Set> getSupportedSchemes() {
Set> supportedSchemes = new LinkedHashSet>();
for (QRCodeSchemeParser parser : getParser()) {
supportedSchemes.addAll(parser.getSupportedSchemes());
}
return supportedSchemes;
}
public Object parse(final String qrCodeText) throws UnsupportedEncodingException {
for (QRCodeSchemeParser parser : getParser()) {
try {
return parser.parse(qrCodeText);
} catch (UnsupportedEncodingException e) {
// go on
}
}
throw new UnsupportedEncodingException("unkonwn QR code scheme: " + qrCodeText);
}
protected Set getParser() {
if (parser == null) {
parser = loadParser();
}
return parser;
}
protected Set loadParser() {
Set result = new LinkedHashSet();
try {
Enumeration resources = this.getClass().getClassLoader().getResources("META-INF/qrcode.meta");
for (URL url : Collections.list(resources)) {
Properties properties = new Properties();
try (InputStream is = url.openStream()) {
properties.load(is);
String prop = properties.getProperty(QRCodeSchemeParser.class.getName());
String[] parserNames = prop.split(",");
for (String className : parserNames) {
result.add(createParserInstance(className));
}
}
}
} catch (Exception e) {
throw new RuntimeException("failed to load schemes", e);
}
result.add(new QRCodeSchemeParserImpl());
return result;
}
protected QRCodeSchemeParser createParserInstance(String className)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
Class> clazz = Class.forName(className.trim());
return (QRCodeSchemeParser) clazz.newInstance();
}
static class QRCodeSchemeParserImpl implements QRCodeSchemeParser {
@Override
public Object parse(String qrCodeText) throws UnsupportedEncodingException {
for (Class extends Schema> type : getSupportedSchemes()) {
Object instance = createInstance(qrCodeText, type);
if (instance != null) {
return instance;
}
}
throw new UnsupportedEncodingException("unkonwn QR code scheme: " + qrCodeText);
}
protected Object createInstance(final String qrCodeText, final Class extends Schema> type) {
try {
return type.getConstructor(null).newInstance(null).parseSchema(qrCodeText);
} catch (Exception e) {
return null;
}
}
@Override
public Set> getSupportedSchemes() {
Set> supportedSchemes = new LinkedHashSet>();
supportedSchemes.add(Girocode.class);
supportedSchemes.add(VCard.class);
supportedSchemes.add(Wifi.class);
supportedSchemes.add(BizCard.class);
supportedSchemes.add(EMail.class);
supportedSchemes.add(EnterpriseWifi.class);
supportedSchemes.add(GeoInfo.class);
supportedSchemes.add(GooglePlay.class);
supportedSchemes.add(ICal.class);
supportedSchemes.add(KddiAu.class);
supportedSchemes.add(MeCard.class);
supportedSchemes.add(MMS.class);
supportedSchemes.add(SMS.class);
supportedSchemes.add(Telephone.class);
supportedSchemes.add(Url.class);
return supportedSchemes;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy