package org.molgenis.data.settings; import org.molgenis.data.DataService; import org.molgenis.data.Entity; import org.molgenis.data.listeners.EntityListener; import org.molgenis.data.listeners.EntityListenersService; import org.molgenis.data.meta.model.EntityType; import org.molgenis.security.core.runas.RunAsSystemProxy; import org.molgenis.util.EntityUtils; import org.springframework.beans.factory.annotation.Autowired; import java.sql.Date; import java.sql.Timestamp; import java.util.ResourceBundle; import static org.molgenis.data.meta.model.Package.PACKAGE_SEPARATOR; import static org.molgenis.data.settings.SettingsPackage.PACKAGE_SETTINGS; /** * Base class for application and plugin settings entities. Settings are read/written from/to data source. */ public abstract class DefaultSettingsEntity implements Entity { private static final long serialVersionUID = 1L; private final String entityName; @Autowired private DataService dataService; @Autowired private EntityListenersService entityListenersService; private transient Entity cachedEntity; public DefaultSettingsEntity(String entityId) { this.entityName = PACKAGE_SETTINGS + PACKAGE_SEPARATOR + entityId; } public EntityType getEntityType() { return RunAsSystemProxy.runAsSystem(() -> { return dataService.getEntityType(entityName); }); } @Override public Iterable<String> getAttributeNames() { return getEntity().getAttributeNames(); } @Override public Object getIdValue() { return getEntity().getIdValue(); } @Override public void setIdValue(Object id) { getEntity().setIdValue(id); } @Override public Object getLabelValue() { return getEntity().getLabelValue(); } @Override public Object get(String attributeName) { return getEntity().get(attributeName); } @Override public String getString(String attributeName) { return getEntity().getString(attributeName); } @Override public Integer getInt(String attributeName) { return getEntity().getInt(attributeName); } @Override public Long getLong(String attributeName) { return getEntity().getLong(attributeName); } @Override public Boolean getBoolean(String attributeName) { return getEntity().getBoolean(attributeName); } @Override public Double getDouble(String attributeName) { return getEntity().getDouble(attributeName); } @Override public Date getDate(String attributeName) { return getEntity().getDate(attributeName); } @Override public java.util.Date getUtilDate(String attributeName) { return getEntity().getUtilDate(attributeName); } @Override public Timestamp getTimestamp(String attributeName) { return getEntity().getTimestamp(attributeName); } @Override public Entity getEntity(String attributeName) { return getEntity().getEntity(attributeName); } @Override public <E extends Entity> E getEntity(String attributeName, Class<E> clazz) { return getEntity().getEntity(attributeName, clazz); } @Override public Iterable<Entity> getEntities(String attributeName) { return getEntity().getEntities(attributeName); } @Override public <E extends Entity> Iterable<E> getEntities(String attributeName, Class<E> clazz) { return getEntity().getEntities(attributeName, clazz); } @Override public void set(String attributeName, Object value) { Entity entity = getEntity(); entity.set(attributeName, value); updateEntity(entity); } @Override public void set(Entity values) { Entity entity = getEntity(); entity.set(values); updateEntity(entity); } /** * Adds a listener for this settings entity that fires on entity updates * * @param settingsEntityListener listener for this settings entity */ public void addListener(SettingsEntityListener settingsEntityListener) { RunAsSystemProxy.runAsSystem(() -> { entityListenersService.addEntityListener(entityName, new EntityListener() { @Override public void postUpdate(Entity entity) { settingsEntityListener.postUpdate(entity); } @Override public Object getEntityId() { return getEntityType().getSimpleName(); } }); }); } /** * Removes a listener for this settings entity that fires on entity updates * * @param settingsEntityListener listener for this settings entity */ public void removeListener(SettingsEntityListener settingsEntityListener) { RunAsSystemProxy.runAsSystem(() -> { entityListenersService.removeEntityListener(entityName, new EntityListener() { @Override public void postUpdate(Entity entity) { settingsEntityListener.postUpdate(entity); } @Override public Object getEntityId() { return getEntityType().getSimpleName(); } }); }); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Entity)) return false; return EntityUtils.equals(this, (Entity) o); } @Override public int hashCode() { return EntityUtils.hashCode(this); } private Entity getEntity() { if (cachedEntity == null) { String id = getEntityType().getSimpleName(); cachedEntity = RunAsSystemProxy.runAsSystem(() -> { Entity entity = dataService.findOneById(entityName, id); // refresh cache on settings update entityListenersService.addEntityListener(entityName, new EntityListener() { @Override public void postUpdate(Entity entity) { cachedEntity = entity; } @Override public Object getEntityId() { return id; } }); return entity; }); } return cachedEntity; } private void updateEntity(Entity entity) { RunAsSystemProxy.runAsSystem(() -> { dataService.update(entityName, entity); ResourceBundle.clearCache(); // cache refresh is handled via entity listener return null; }); } }