package ru.semiot.commons.namespaces; import java.lang.reflect.Field; import java.net.MalformedURLException; import java.net.URI; import java.util.Arrays; import java.util.List; import java.util.Optional; public class NamespaceUtils { private static final String PREFIX = "PREFIX"; private static final String BLANK = " "; private static final String COLON = ":"; private static final String LT = "<"; private static final String GT = ">"; private static final String NEWLINE = "\n"; private static final String FIELD_PREFIX = "PREFIX"; private static final String FIELD_URI = "URI"; private static final String FIELD_NS = "NS"; private static final String GRID = "#"; private static final String SLASH = "/"; private static final String PROTOCOL_DELIMITER = "://"; private static StringBuilder _toSPARQLPrologue(Class... namespaces) { StringBuilder builder = new StringBuilder(); for (Class<? extends Namespace> clazz : namespaces) { try { List<Field> fields = Arrays.asList(clazz.getDeclaredFields()); Field f_uri = fields.stream().filter((f) -> { return f.getName().equalsIgnoreCase(FIELD_URI) || f.getName().equalsIgnoreCase(FIELD_NS); }).findFirst().get(); Optional<Field> f_prefix_opt = fields.stream().filter((f) -> { return f.getName().equalsIgnoreCase(FIELD_PREFIX); }).findFirst(); String prefix; if (f_prefix_opt.isPresent()) { Field f_prefix = f_prefix_opt.get(); f_prefix.setAccessible(true); prefix = (String) f_prefix.get(null); } else { prefix = clazz.getSimpleName().toLowerCase(); } f_uri.setAccessible(true); if (f_uri.isAccessible() && !clazz.isAnonymousClass()) { Object uri = f_uri.get(null); if (uri instanceof String) { builder.append(PREFIX).append(BLANK).append(prefix) .append(COLON).append(BLANK).append(LT) .append(uri).append(GT).append(NEWLINE); continue; } } throw new IllegalStateException(); } catch (Throwable ex) { throw new IllegalStateException( clazz.getName() + " : " + ex.getMessage(), ex); } } return builder; } /** * Generates prologue for SPARQL queries. * <p> * {@code namespaces} must have a public static field named {@code uri} or * {@code ns} (ignoring case) which is {@code String} containing the uri of * the namespace. * * @param namespaces * @return */ public static String toSPARQLPrologue(Class... namespaces) { return _toSPARQLPrologue(namespaces).toString(); } public static String newSPARQLQuery(String query, Class... namespaces) { return _toSPARQLPrologue(namespaces).append(query).toString(); } public static String extractLocalName(String uri) { return extractLocalName(URI.create(uri)); } public static String extractLocalName(URI uri) { String uriString = uri.toASCIIString() .replace(uri.getScheme() + PROTOCOL_DELIMITER + uri.getHost(), ""); int index; if (uriString.contains(GRID)) { index = uriString.indexOf(GRID) + 1; } else if (uriString.contains(SLASH)) { index = uriString.lastIndexOf(SLASH) + 1; } else { return null; } if (uriString.length() > index) { return uriString.substring(index); } else { return null; } } }