package org.molgenis.data.annotation.core.resources.impl; import org.molgenis.data.Entity; import org.molgenis.data.Query; import org.molgenis.data.Repository; import org.molgenis.data.annotation.core.resources.Resource; import org.molgenis.data.annotation.core.resources.ResourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; /** * Implementation of {@link Resource}, a file-based repository. The location of the file is configured in * MolgenisSettings. */ public abstract class ResourceImpl implements Resource { private final String name; private final ResourceConfig config; // the file the current repository works on private volatile File file; // the current repository private volatile Repository<Entity> repository; private static final Logger LOG = LoggerFactory.getLogger(ResourceImpl.class); /** * Creates a new {@link Resource} * * @param name the name of the Resource * @param config ResourceConfig that configure the location of the file */ public ResourceImpl(String name, ResourceConfig config) { this.name = name; this.config = config; } /** * Indicates if the resource is available. * * @return indication if this resource is available */ @Override public synchronized boolean isAvailable() { if (repository != null && needsRefresh()) { repository = null; file = null; } final File file = getFile(); return file != null && file.exists(); } /** * Searches the repository if it is available. * * @param q the {@link Query} to use * @return {@link Entity}s found * @throws NullPointerException if the repository is not available */ @Override public Iterable<Entity> findAll(Query<Entity> q) { return () -> getRepository().findAll(q).iterator(); } private boolean needsRefresh() { File newFile = config.getFile(); boolean needsRefresh = file != null && !file.equals(newFile); if (needsRefresh) { repository = null; file = null; } return repository == null; } private Repository<Entity> getRepository() { if (repository == null && isAvailable()) { initialize(); } return repository; } private synchronized void initialize() { RepositoryFactory repositoryFactory = getRepositoryFactory(); if (isAvailable() && repository == null) { try { file = getFile(); if (file != null) { repository = repositoryFactory.createRepository(file); } } catch (Exception e) { LOG.warn("Resource {} failed to create Repository for file {}.", name, file, e); } } } private synchronized File getFile() { return config.getFile(); } @Override public String getName() { return name; } }