// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.opendata.core.modules;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.gui.preferences.SourceEditor.ExtendedSourceEntry;
import org.openstreetmap.josm.gui.preferences.SourceEntry;
import org.openstreetmap.josm.gui.preferences.SourceProvider;
import org.openstreetmap.josm.plugins.opendata.OdPlugin;
import org.openstreetmap.josm.plugins.opendata.core.OdConstants;
import org.openstreetmap.josm.plugins.opendata.core.datasets.AbstractDataSetHandler;
public abstract class AbstractModule implements Module {
protected final List<Class<? extends AbstractDataSetHandler>> handlers = new ArrayList<>();
private final List<AbstractDataSetHandler> instanciatedHandlers = new ArrayList<>();
protected final ModuleInformation info;
public AbstractModule(ModuleInformation info) {
this.info = info;
}
@Override
public ModuleInformation getModuleInformation() {
return info;
}
@Override
public List<Class<? extends AbstractDataSetHandler>> getHandlers() {
return handlers;
}
@Override
public String getDisplayedName() {
return info.name;
}
@Override
public SourceProvider getMapPaintStyleSourceProvider() {
final List<SourceEntry> sources = new ArrayList<>();
for (AbstractDataSetHandler handler : getInstanciatedHandlers()) {
ExtendedSourceEntry src;
if (handler != null && (src = handler.getMapPaintStyle()) != null) {
// Copy style sheet to disk to allow JOSM to load it at startup
// (even making the plugin "early" does not allow it)
String path = OdPlugin.getInstance().getResourcesDirectory() + File.separator
+ src.url.replace(OdConstants.PROTO_RSRC, "").replace('/', File.separatorChar);
int n = 0;
byte[] buffer = new byte[4096];
try (InputStream in = getClass().getResourceAsStream(
src.url.substring(OdConstants.PROTO_RSRC.length()-1));
FileOutputStream out = new FileOutputStream(path)) {
String dir = path.substring(0, path.lastIndexOf(File.separatorChar));
if (new File(dir).mkdirs() && Main.isDebugEnabled()) {
Main.debug("Created directory: "+dir);
}
while ((n = in.read(buffer)) > 0) {
out.write(buffer, 0, n);
}
// Add source pointing to the local file
src.url = OdConstants.PROTO_FILE+path;
sources.add(src);
} catch (IOException e) {
Main.error(e.getMessage());
}
}
}
return sources.isEmpty() ? null : new SourceProvider() {
@Override
public Collection<SourceEntry> getSources() {
return sources;
}
};
}
@Override
public SourceProvider getPresetSourceProvider() {
final List<SourceEntry> sources = new ArrayList<>();
for (AbstractDataSetHandler handler : getInstanciatedHandlers()) {
if (handler != null && handler.getTaggingPreset() != null) {
sources.add(handler.getTaggingPreset());
}
}
return sources.isEmpty() ? null : new SourceProvider() {
@Override
public Collection<SourceEntry> getSources() {
return sources;
}
};
}
@Override
public final List<AbstractDataSetHandler> getNewlyInstanciatedHandlers() {
List<AbstractDataSetHandler> result = new ArrayList<>();
for (Class<? extends AbstractDataSetHandler> handlerClass : handlers) {
if (handlerClass != null) {
try {
result.add(handlerClass.getConstructor().newInstance());
} catch (ReflectiveOperationException | IllegalArgumentException | SecurityException t) {
Main.error(t, "Cannot instantiate "+handlerClass+" because of "+t.getClass().getName());
}
}
}
return result;
}
private List<AbstractDataSetHandler> getInstanciatedHandlers() {
if (instanciatedHandlers.isEmpty()) {
instanciatedHandlers.addAll(getNewlyInstanciatedHandlers());
}
return instanciatedHandlers;
}
}