package semweb; import static com.hp.hpl.jena.rdf.model.ResourceFactory.*; import static semweb.Predicate.*; import static semweb.Prefix.*; import java.io.*; import java.net.*; import java.util.*; import java.util.logging.*; import com.hp.hpl.jena.rdf.model.*; /** * Manages data from the sematic web related to place names literals. * * @author Jo Pol */ public class MashupImpl implements MashUp { private static final Logger logger = Logger.getLogger(MashupImpl.class.getName()); private static final Map PREFIXES = initPrefixes(); private static final Property hasLabel = createProperty(rdfs.uri + "hasLabel"); private static final Property isDefineBy = createProperty(rdfs.uri + "isDefinedBy"); private final URI idPrefix; private final File file; private final String language; private Model model; /** * Downloads and links external data for all places. * * @param idPrefix * used to construct new URIs. * @param file * a file with one of the extension rdf/n3/ttl. Intermediate changes to the file by anything * except methods of this instance, will be overwritten by methods of this instance. */ public MashupImpl(final URI idPrefix, final File file) { this.file = file; this.idPrefix = idPrefix; final String extension = file.getName().trim().replaceAll(".*\\.", "").toLowerCase(); language = Extension.valueOf(extension).language(); } /** * Downloads resources from geonames and links them to place name literals. Constructs * *
     * <id> rdf:label KEY;
     *            rdfs:isDefinedBy <http://sws.geonames.org/VALUE>.
     * 
* * Overwrites possible previous contents of the file. * * @param places * KEY: place name literal. For gedcom files typically
* the unique values of INDI:*:PLAC and FAM:*:PLAC
* for example ", Washington, , , , DC, USA"
* VALUE: GeoNameId's (the numeric component of the URIs)
* uri example http://sws.geonames.org/4140963/about.rdf * @throws FileNotFoundException */ public void create(final Map places) throws FileNotFoundException { logger.fine("create: "+Arrays.deepToString(places.keySet().toArray())); model = ModelFactory.createDefaultModel(); model.setNsPrefixes(PREFIXES); model.write(new FileOutputStream(file), language); addPlaces(places); } /** * Like {@link #create(Map)} but adds places not yet in the file. * * @param places * as {@link #create(Map, IdGenerator, File)} * @throws FileNotFoundException */ public void update(final Map places) throws FileNotFoundException { logger.fine("update: "+Arrays.deepToString(places.keySet().toArray())); readModel(); addPlaces(places); model.write(new FileOutputStream(file), language); } private void addPlaces(final Map places) throws FileNotFoundException { for (final String place : places.keySet()) { final String geoNameId = places.get(place); final Resource subject = createResource(idPrefix + geoNameId); if (!model.containsLiteral(subject, hasLabel, place)) { final String uri = "http://sws.geonames.org/" + geoNameId + "/"; model.read(uri + "about.rdf"); model.add(subject, hasLabel, place); model.add(subject, isDefineBy, createResource(uri)); readRelated(uri); } } model.write(new FileOutputStream(file), language); } private void readRelated(final String gnUri) { for (final String uri : runQuery(gnUri, seeAlso)) { model.read(uri + ".rdf"); for (final String uri2 : runQuery(uri, seeAlso)) model.read(uri2 + ".rdf"); for (final String uri2 : runQuery(uri, sameAs)) model.read(uri2 + ".rdf"); } } private List runQuery(final String uri, final Predicate predicate) { final String f = "select distinct str(?n) {<%s> %s ?n. FILTER regexp(str(?n),'dbpedia.org')}"; final String q = String.format(f, uri, predicate.toString()); logger.warning("not yet implemented: " + q); // TODO execute query return new ArrayList(); } private void readModel() throws FileNotFoundException { if (model == null) { model = ModelFactory.createDefaultModel(); model.read(new FileInputStream(file), (String) null, language); } } private static final Map initPrefixes() { final Map result = new HashMap(); for (final Prefix prefix : Prefix.values()) result.put(prefix.name(), prefix.uri); return result; } public static void main(final String[] args) throws FileNotFoundException, URISyntaxException { logger.setLevel(Level.FINEST); logger.log(Level.INFO, "test started"); final MashUp mashUp = new MashupImpl(new URI("http://my.domain.com/gedcom/places/"), new File("tmp.ttl")); final Map places = new HashMap(); places.put(", Washington, , , , DC, USA", "4140963"); places.put(", Boston, , , Suffolk Co, MA, USA", "4930956"); places.put(", Dunganstown, , , Wexford Co, , Ireland", "2964529"); mashUp.create(places); places.put(", New York City, , , , NY, USA", "5128581"); places.put(", Malden, , , Middlesex Co, MA, USA", "4942939"); mashUp.update(places); logger.log(Level.INFO, "test finished"); } }