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

com.github.anno4j.Anno4j Maven / Gradle / Ivy

Go to download

Read and write API for W3C Web Annotation Data Model (http://www.w3.org/TR/annotation-model/) and W3C Open Annotation Data Model (http://www.openannotation.org/spec/core/)

There is a newer version: 2.4
Show newest version
package com.github.anno4j;

import com.github.anno4j.annotations.Evaluator;
import com.github.anno4j.annotations.Partial;
import com.github.anno4j.model.impl.ResourceObject;
import com.github.anno4j.querying.QueryService;
import com.github.anno4j.querying.evaluation.LDPathEvaluatorConfiguration;
import com.github.anno4j.querying.extension.QueryEvaluator;
import com.github.anno4j.querying.extension.TestEvaluator;
import org.apache.commons.lang3.ClassUtils;
import org.apache.http.annotation.NotThreadSafe;
import org.apache.marmotta.ldpath.api.functions.SelectorFunction;
import org.apache.marmotta.ldpath.api.functions.TestFunction;
import org.apache.marmotta.ldpath.api.selectors.NodeSelector;
import org.apache.marmotta.ldpath.api.tests.NodeTest;
import org.openrdf.idGenerator.IDGenerator;
import org.openrdf.idGenerator.IDGeneratorAnno4jURN;
import org.openrdf.model.Resource;
import org.openrdf.model.URI;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.config.RepositoryConfigException;
import org.openrdf.repository.object.ObjectConnection;
import org.openrdf.repository.object.ObjectRepository;
import org.openrdf.repository.object.config.ObjectRepositoryConfig;
import org.openrdf.repository.object.config.ObjectRepositoryFactory;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.sail.memory.MemoryStore;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.reflections.scanners.TypeAnnotationsScanner;
import org.reflections.util.ClasspathHelper;
import org.reflections.util.ConfigurationBuilder;
import org.reflections.util.FilterBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URL;
import java.util.*;


/**
 * Read and write API for W3C Web Annotation Data Model (http://www.w3.org/TR/annotation-model/) and W3C Open Annotation Data Model (http://www.openannotation.org/spec/core/).
 * 

*

Anno4j can be configured by using the specific setter-methodes (e.g. setIdGenerator, setRepository). A default configuration (in-memory SPARQL endpoint) will be used if no configuration is set. *

*

Anno4j methods are not thread-safe. Use Anno4j transactions in threaded environment. */ @NotThreadSafe public class Anno4j implements TransactionCommands { /** * Logger of this class. */ private final Logger logger = LoggerFactory.getLogger(Anno4j.class); private final URI defaultContext; private IDGenerator idGenerator; /** * Configured openrdf/sesame repository for connecting a local/remote SPARQL endpoint. */ private Repository repository; /** * Wrapper of the repository field for alibaba, will be updated if a new repository is set. */ private ObjectRepository objectRepository; /** * Wrapper to store the evaluators for the different LDPath components */ private LDPathEvaluatorConfiguration evaluatorConfiguration = new LDPathEvaluatorConfiguration(); /** * Stores alls partial implementations of the defined interfaces, such as the ResourceObject or the * Annotation interface. */ private Set> partialClasses; public Anno4j() throws RepositoryException, RepositoryConfigException { this(new SailRepository(new MemoryStore())); } public Anno4j(URI defaultContext) throws RepositoryException, RepositoryConfigException { this(new SailRepository(new MemoryStore()), defaultContext); } public Anno4j(IDGenerator idGenerator) throws RepositoryException, RepositoryConfigException { this(new SailRepository(new MemoryStore()), idGenerator, null); } public Anno4j(IDGenerator idGenerator, URI defaultContext) throws RepositoryException, RepositoryConfigException { this(new SailRepository(new MemoryStore()), idGenerator, defaultContext); } public Anno4j(Repository repository) throws RepositoryException, RepositoryConfigException { this(repository, new IDGeneratorAnno4jURN(), null); } public Anno4j(Repository repository, IDGenerator idGenerator) throws RepositoryException, RepositoryConfigException { this(repository, idGenerator, null); } public Anno4j(Repository repository, URI defaultContext) throws RepositoryException, RepositoryConfigException { this(repository, new IDGeneratorAnno4jURN(), defaultContext); } public Anno4j(Repository repository, IDGenerator idGenerator, URI defaultContext) throws RepositoryConfigException, RepositoryException { this.idGenerator = idGenerator; this.defaultContext = defaultContext; Set classpath = new HashSet<>(); classpath.addAll(ClasspathHelper.forClassLoader()); classpath.addAll(ClasspathHelper.forJavaClassPath()); classpath.addAll(ClasspathHelper.forManifest()); classpath.addAll(ClasspathHelper.forPackage("")); Reflections annotatedClasses = new Reflections(new ConfigurationBuilder() .setUrls(classpath) .useParallelExecutor() .filterInputsBy(FilterBuilder.parsePackages("-java, -javax, -sun, -com.sun")) .setScanners(new SubTypesScanner(), new TypeAnnotationsScanner())); // Bugfix: Searching for Reflections creates a lot ot Threads, that are not closed at the end by themselves, // so we close them manually. annotatedClasses.getConfiguration().getExecutorService().shutdown(); // find classes with @Partial annotation this.partialClasses = annotatedClasses.getTypesAnnotatedWith(Partial.class, true); scanForEvaluators(annotatedClasses); if(!repository.isInitialized()) { repository.initialize(); } this.setRepository(repository); } private void scanForEvaluators(Reflections annotatedClasses) { Set> defaultEvaluatorAnnotations = annotatedClasses.getTypesAnnotatedWith(Evaluator.class, true); Map, Class> testFunctionEvaluators = new HashMap<>(); Map, Class> defaultEvaluators = new HashMap<>(); Map, Class> testEvaluators = new HashMap<>(); Map, Class> functionEvaluators = new HashMap<>(); for (Class clazz : defaultEvaluatorAnnotations) { Evaluator evaluator = (Evaluator) clazz.getAnnotation(Evaluator.class); Class[] functionClasses = evaluator.value(); for(Class functionClass : functionClasses) { if (ClassUtils.isAssignable(functionClass, TestFunction.class)) { logger.debug("Found evaluator {} for TestFunction {}", clazz.getCanonicalName(), functionClass.getCanonicalName()); testFunctionEvaluators.put((Class) functionClass, clazz); } else if (ClassUtils.isAssignable(functionClass, NodeTest.class)) { logger.debug("Found evaluator {} for NodeTest {}", clazz.getCanonicalName(), functionClass.getCanonicalName()); testEvaluators.put((Class) functionClass, clazz); } else if (ClassUtils.isAssignable(functionClass, SelectorFunction.class)) { logger.debug("Found evaluator {} for NodeFunction {}", clazz.getCanonicalName(), functionClass.getCanonicalName()); functionEvaluators.put((Class) functionClass, clazz); } else { logger.debug("Found evaluator {} for NodeSelector {}", clazz.getCanonicalName(), functionClass.getCanonicalName()); defaultEvaluators.put((Class) functionClass, clazz); } } } evaluatorConfiguration.setDefaultEvaluators(defaultEvaluators); evaluatorConfiguration.setTestEvaluators(testEvaluators); evaluatorConfiguration.setTestFunctionEvaluators(testFunctionEvaluators); evaluatorConfiguration.setFunctionEvaluators(functionEvaluators); } private ObjectConnection createObjectConnection(URI context) throws RepositoryException { ObjectConnection connection = objectRepository.getConnection(); if(context != null) { connection.setReadContexts(context); connection.setInsertContext(context); connection.setRemoveContexts(context); } else if (defaultContext != null) { connection.setReadContexts(defaultContext); connection.setInsertContext(defaultContext); connection.setRemoveContexts(defaultContext); } return connection; } /** * {@inheritDoc } */ @Override public void persist(ResourceObject resource) throws RepositoryException { Transaction transaction = createTransaction(); if(defaultContext != null) { transaction.setAllContexts(defaultContext); } transaction.persist(resource); } /** * Writes the resource object to the configured SPARQL endpoint with a corresponding INSERT query. * @param resource resource object to write to the SPARQL endpoint * @param context Graph context to query * @throws RepositoryException */ public void persist(ResourceObject resource, URI context) throws RepositoryException { Transaction transaction = createTransaction(); transaction.setAllContexts(context); transaction.persist(resource); } /** * {@inheritDoc } */ @Override public T findByID(Class type, String id) throws RepositoryException { Transaction transaction = createTransaction(); if(defaultContext != null) { transaction.setAllContexts(defaultContext); } return transaction.findByID(type, id); } /** * {@inheritDoc } */ @Override public T findByID(Class type, URI id) throws RepositoryException { Transaction transaction = createTransaction(); if(defaultContext != null) { transaction.setAllContexts(defaultContext); } return transaction.findByID(type, id); } /** * {@inheritDoc } */ @Override public void clearContext(URI context) throws RepositoryException { Transaction transaction = createTransaction(); transaction.clearContext(context); transaction.close(); } /** * {@inheritDoc } */ @Override public void clearContext(String context) throws RepositoryException { Transaction transaction = createTransaction(); transaction.clearContext(context); transaction.close(); } /** * {@inheritDoc } */ @Override public List findAll(Class type) throws RepositoryException { Transaction transaction = createTransaction(); if(defaultContext != null) { transaction.setAllContexts(defaultContext); } return transaction.findAll(type); } public List findAll(Class type, URI context) throws RepositoryException { Transaction transaction = createTransaction(); transaction.setAllContexts(context); return transaction.findAll(type); } /** * {@inheritDoc } */ @Override public T createObject(Class clazz) throws RepositoryException, IllegalAccessException, InstantiationException { return createObject(clazz, null); } @Override public T createObject(Class clazz, Resource id) throws RepositoryException, IllegalAccessException, InstantiationException { Transaction transaction = createTransaction(); if(defaultContext != null) { transaction.setAllContexts(defaultContext); } return transaction.createObject(clazz, id); } /** * Creates a instance of the given class. * @param clazz Class of the instance to create. Can be an annotated interface. * @param context The graph context where the triples are inserted into. can be null for default graph. * @return A instance of the given class. */ public T createObject(Class clazz, URI context) throws RepositoryException, IllegalAccessException, InstantiationException { return createObject(clazz, context, null); } public T createObject(Class clazz, URI context, Resource id) throws RepositoryException, IllegalAccessException, InstantiationException { Transaction transaction = createTransaction(); transaction.setAllContexts(context); return transaction.createObject(clazz, id); } /** * {@inheritDoc } */ @Override public QueryService createQueryService() throws RepositoryException { Transaction transaction = createTransaction(); if(defaultContext != null) { transaction.setAllContexts(defaultContext); } return transaction.createQueryService(); } /** * Create query service * * @param context context to query * @return query service object for specified type */ public QueryService createQueryService(URI context) throws RepositoryException { Transaction transaction = createTransaction(); transaction.setAllContexts(context); return transaction.createQueryService(); } /** * Getter for the configured Repository instance (Connector for local/remote SPARQL repository). * * @return configured Repository instance */ public Repository getRepository() { return repository; } /** * Configures the Repository (Connector for local/remote SPARQL repository) to use in Anno4j. * * @param repository Repository to use in Anno4j. * @throws RepositoryException * @throws RepositoryConfigException */ public void setRepository(Repository repository) throws RepositoryException, RepositoryConfigException { this.repository = repository; // update alibaba wrapper ObjectRepositoryFactory factory = new ObjectRepositoryFactory(); ObjectRepositoryConfig config = factory.getConfig(); if(partialClasses != null) { for(Class clazz : this.partialClasses){ config.addBehaviour(clazz); } } this.objectRepository = new ObjectRepositoryFactory().createRepository(config, repository); this.objectRepository.setIdGenerator(idGenerator); } /** * Getter for configured ObjectRepository (openrdf/alibaba wrapper for the internal Repository). * * @return configured ObjectRepository. */ public ObjectRepository getObjectRepository() { return objectRepository; } public IDGenerator getIdGenerator() { return idGenerator; } public void setIdGenerator(IDGenerator idGenerator) { this.idGenerator = idGenerator; this.objectRepository.setIdGenerator(idGenerator); } public URI getDefaultContext() { return defaultContext; } public Transaction createTransaction() throws RepositoryException { return new Transaction(objectRepository, evaluatorConfiguration); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy