All Downloads are FREE. Search and download functionalities are using the official Maven repository.

at.newmedialab.ldclient.service.LDCache Maven / Gradle / Ivy

The newest version!
/**
 * Copyright (C) 2013 Salzburg Research.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package at.newmedialab.ldclient.service;

import at.newmedialab.ldclient.api.LDCacheProvider;
import at.newmedialab.ldclient.exception.LDClientException;
import at.newmedialab.ldclient.model.CacheEntry;
import at.newmedialab.ldclient.model.ClientResponse;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.repository.RepositoryConnection;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Add file description here!
 * 

* Author: Sebastian Schaffert */ public class LDCache { private static final String CTX_CACHE = "http://www.newmedialab.at/ldclient/cache"; private Logger log = LoggerFactory.getLogger(LDCache.class); private LDClient clientService; private LDEndpoints endpointService; private ThreadLocal inProgress = new ThreadLocal(); private LDCacheProvider cacheProvider; // lock a resource while refreshing it so that not several threads trigger a refresh at the same time private HashMap resourceLocks; private Configuration config; public LDCache(LDCacheProvider ldCacheProvider) { log.info("Linked Data Caching Service initialising ..."); try { config = new PropertiesConfiguration("ldclient.properties"); } catch (ConfigurationException e) { log.warn("could not load configuration file ldclient.properties from current directory, home directory, or classpath"); } resourceLocks = new HashMap(); cacheProvider = ldCacheProvider; clientService = new LDClient(); endpointService = new LDEndpoints(); } private void lockResource(URI resource) { Lock lock; synchronized (resourceLocks) { lock = resourceLocks.get(resource); if(lock == null) { lock = new ReentrantLock(); resourceLocks.put(resource,lock); } } lock.lock(); } private void unlockResource(URI resource) { Lock lock; synchronized (resourceLocks) { lock = resourceLocks.remove(resource); } if(lock != null) { lock.unlock(); } } /** * Refresh the cached resource passed as argument. The method will do nothing for local resources. * Calling the method will carry out the following tasks: * 1. check whether the resource is a remote resource; if no, returns immediately * 2. check whether the resource has a cache entry; if no, goto 4 * 3. check whether the expiry time of the cache entry has passed; if no, returns immediately * 4. retrieve the triples for the resource from the Linked Data Cloud using the methods offered by the * LinkedDataClientService (registered endpoints etc); returns immediately if the result is null or * an exception is thrown * 5. remove all old triples for the resource and add all new triples for the resource * 6. create new expiry information of the cache entry and persist it in the transaction * * @param resource */ public void refreshResource(URI resource) { lockResource(resource); try { // 2. check whether the resource has a cache entry; if no, goto 4 CacheEntry entry = getCacheEntry(resource); // 3. check whether the expiry time of the cache entry has passed; if no, returns immediately if(entry != null && entry.getExpiryDate().after(new Date())) { log.info("not refreshing resource {}, as the cached entry is not yet expired",resource); return; } // 4. log.debug("refreshing resource {}",resource); try { ClientResponse response = clientService.retrieveResource(resource); if(response != null) { log.info("refreshed resource {}",resource); URI context = cacheProvider.getTripleRepository().getValueFactory().createURI(CTX_CACHE); RepositoryConnection lmfConnection = cacheProvider.getTripleRepository().getConnection(); RepositoryConnection respConnection = response.getTriples().getConnection(); lmfConnection.remove(resource,null,null,context); RepositoryResult triples = respConnection.getStatements(null,null,null,true); while(triples.hasNext()) { Statement triple = triples.next(); try { lmfConnection.add(triple,context); } catch (RuntimeException ex) { log.warn("not adding triple {}: an exception occurred ({})",triple,ex.getMessage()); } } lmfConnection.commit(); lmfConnection.close(); respConnection.close(); CacheEntry newEntry = new CacheEntry(); newEntry.setResource(resource); newEntry.setExpiryDate(response.getExpires()); newEntry.setLastRetrieved(new Date()); if(entry != null) { newEntry.setUpdateCount(entry.getUpdateCount()+1); } else { newEntry.setUpdateCount((long)1); } cacheProvider.getMetadataRepository().put(resource.stringValue(),newEntry); } } catch (LDClientException e) { // on exception, save an expiry information and retry in one day CacheEntry newEntry = new CacheEntry(); newEntry.setResource(resource); newEntry.setExpiryDate(new Date(System.currentTimeMillis() + config.getInt("expiry", 86400)*1000)); newEntry.setLastRetrieved(new Date()); if(entry != null) { newEntry.setUpdateCount(entry.getUpdateCount()+1); } else { newEntry.setUpdateCount((long)1); } cacheProvider.getMetadataRepository().put(resource.stringValue(), newEntry); log.error("refreshing the remote resource {} from the Linked Data Cloud failed ({})",resource,e.getMessage()); return; } catch (RepositoryException e) { log.error("repository error while refreshing the remote resource {} from the Linked Data Cloud", resource, e); return; } } finally { unlockResource(resource); } } private CacheEntry getCacheEntry(URI resource) { return cacheProvider.getMetadataRepository().get(resource.stringValue()); } public LDEndpoints getEndpointService() { return endpointService; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy