
fr.vergne.translation.impl.OnDemandProject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of translation-core Show documentation
Show all versions of translation-core Show documentation
Basic features to support a translation project.
The newest version!
package fr.vergne.translation.impl;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import fr.vergne.translation.TranslationEntry;
import fr.vergne.translation.TranslationEntry.TranslationListener;
import fr.vergne.translation.TranslationMap;
import fr.vergne.translation.TranslationMetadata;
import fr.vergne.translation.TranslationMetadata.Field;
import fr.vergne.translation.TranslationMetadata.FieldListener;
import fr.vergne.translation.TranslationProject;
import fr.vergne.translation.util.EntryFilter;
import fr.vergne.translation.util.Feature;
import fr.vergne.translation.util.MapNamer;
import fr.vergne.translation.util.MultiReader;
import fr.vergne.translation.util.Writer;
/**
* An {@link OnDemandProject} aims at accessing to the resources of a
* {@link TranslationProject} on demand, thus retrieving each
* {@link TranslationMap} only when requested.
*
* @author Matthieu VERGNE
*
* @param
* @param
*/
public class OnDemandProject, TMapID, TMap extends TranslationMap>
implements TranslationProject {
private static final Writer>> DEFAULT_SAVER = new Writer>>() {
@Override
public void write(
OnDemandProject, ?, ? extends TranslationMap>> project) {
for (TranslationMap> map : project.modifiedMaps) {
map.saveAll();
}
}
};
private final Set ids;
private final MultiReader mapReader;
private final Writer super OnDemandProject> projectSaver;
private final Map> cache = new HashMap>();
private final Set modifiedMaps = new HashSet<>();
/**
* Instantiate an {@link OnDemandProject} for a given set of
* {@link TranslationMap}s. Only the IDs of the {@link TranslationMap}s are
* stored, the {@link TranslationMap}s themselves are retrieved on demand.
* The overall saving strategy is provided by a custom {@link Writer}.
*
* @param ids
* the {@link TranslationMap} IDs of this
* {@link TranslationProject}
* @param mapReader
* the {@link MultiReader} to use for {@link #getMap(Object)}
* @param projectSaver
* the {@link Writer} to use for {@link #saveAll()}
*/
public OnDemandProject(Collection ids,
MultiReader mapReader,
Writer super OnDemandProject> projectSaver) {
this.ids = Collections.unmodifiableSet(new LinkedHashSet<>(ids));
this.mapReader = mapReader;
this.projectSaver = projectSaver;
}
/**
* Instantiate an {@link OnDemandProject} for a given set of
* {@link TranslationMap}s. Only the IDs of the {@link TranslationMap}s are
* stored, the {@link TranslationMap}s themselves are retrieved on demand.
* For saving the project, a naive strategy is used: each modified
* {@link TranslationMap} is saved separately. If you want a smarter
* strategy, use the most extended constructor.
*
* @param ids
* the {@link TranslationMap} IDs of this
* {@link TranslationProject}
* @param mapReader
* the {@link MultiReader} to use for {@link #getMap(Object)}
*/
public OnDemandProject(Collection ids,
MultiReader reader) {
this(ids, reader, DEFAULT_SAVER);
}
@Override
public Iterator iterator() {
return ids.iterator();
}
@Override
public TMap getMap(TMapID id) {
WeakReference reference = cache.get(id);
if (reference == null || reference.get() == null) {
final TMap map = mapReader.read(id);
TranslationListener translationListener = new TranslationListener() {
@Override
public void translationUpdated(String newTranslation) {
modifiedMaps.add(map);
}
@Override
public void translationStored() {
// ignored
}
};
FieldListener metadataListener = new FieldListener() {
@Override
public void fieldUpdated(Field field, T newValue) {
modifiedMaps.add(map);
}
@Override
public void fieldStored(Field field) {
// ignored
}
};
for (TranslationEntry extends TranslationMetadata> entry : map) {
entry.addTranslationListener(translationListener);
entry.getMetadata().addFieldListener(metadataListener);
}
cache.put(id, new WeakReference(map));
return map;
} else {
return reference.get();
}
}
@Override
public int size() {
return ids.size();
}
@Override
public void saveAll() {
projectSaver.write(this);
modifiedMaps.clear();
}
@Override
public void resetAll() {
for (TMap map : modifiedMaps) {
map.resetAll();
}
modifiedMaps.clear();
}
private final Collection> mapNamers = new LinkedHashSet<>();
@Override
public Collection> getMapNamers() {
return mapNamers;
}
public void addMapNamer(MapNamer namer) {
mapNamers.add(namer);
}
private final Collection features = new LinkedHashSet<>();
@Override
public Collection getFeatures() {
return features;
}
public void addFeature(Feature feature) {
features.add(feature);
}
private final Collection> filters = new HashSet>();
@Override
public Collection> getEntryFilters() {
return filters;
}
public void addEntryFilter(EntryFilter filter) {
filters.add(filter);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy