package edu.sc.seis.sod.process.waveform;
import java.io.File;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.velocity.VelocityContext;
import org.w3c.dom.Element;
import edu.iris.Fissures.network.ChannelImpl;
import edu.iris.Fissures.seismogramDC.LocalSeismogramImpl;
import edu.sc.seis.fissuresUtil.cache.CacheEvent;
import edu.sc.seis.fissuresUtil.display.configuration.DOMHelper;
import edu.sc.seis.fissuresUtil.hibernate.ChannelGroup;
import edu.sc.seis.sod.status.FissuresFormatter;
import edu.sc.seis.sod.status.Pass;
import edu.sc.seis.sod.status.StringTree;
import edu.sc.seis.sod.status.StringTreeLeaf;
import edu.sc.seis.sod.subsetter.VelocityFileElementParser;
import edu.sc.seis.sod.velocity.ContextWrangler;
import edu.sc.seis.sod.velocity.SimpleVelocitizer;
import edu.sc.seis.sod.velocity.network.VelocityChannel;
public abstract class AbstractFileWriter {
public AbstractFileWriter(String workingDir, String fileTemplate, String prefix) {
this.workingDir = workingDir;
this.origTemplate = fileTemplate;
this.prefix = prefix;
if(!INDEX_VAR.matcher(fileTemplate).matches()) {
fileTemplate += "${index}";
}
VelocityFileElementParser parser = new VelocityFileElementParser(workingDir, fileTemplate);
this.template = parser.getTemplate();
this.prefix = prefix;
}
public String generate(CacheEvent event,
ChannelImpl channel,
LocalSeismogramImpl representativeSeismogram,
int index,
int numSeismograms) {
VelocityContext ctx = ContextWrangler.createContext(event);
if(numSeismograms > 1) {
ctx.put("index", "." + (index+1)); // names index base 1, array is base 0
} else {
ctx.put("index", "");
}
ctx.put("prefix", prefix);
ContextWrangler.insertIntoContext(representativeSeismogram, channel, ctx);
return FissuresFormatter.filize(velocitizer.evaluate(template, ctx));
}
public String generate(CacheEvent event,
ChannelImpl channel,
ChannelImpl otherChannel,
int index,
Map<String, Object> extras) {
VelocityContext ctx = ContextWrangler.createContext(event);
if(index > 0) {
ctx.put("index", "." + index);
} else {
ctx.put("index", "");
}
ctx.put("prefix", prefix);
ContextWrangler.insertIntoContext(channel, ctx);
ctx.put("otherChannel", new VelocityChannel(otherChannel));
for (String key : extras.keySet()) {
ctx.put(key, extras.get(key));
}
return FissuresFormatter.filize(velocitizer.evaluate(template, ctx));
}
public String generate(CacheEvent event,
ChannelGroup channelGroup,
int index,
Map<String, Object> extras) {
VelocityContext ctx = ContextWrangler.createContext(event);
if(index > 0) {
ctx.put("index", "." + index);
} else {
ctx.put("index", "");
}
ctx.put("prefix", prefix);
ContextWrangler.insertIntoContext(channelGroup, ctx);
for (String key : extras.keySet()) {
ctx.put(key, extras.get(key));
}
return FissuresFormatter.filize(velocitizer.evaluate(template, ctx));
}
public StringTree checkParentDirs(String filename) {
File out = new File(filename);
File parent = out.getParentFile();
if(parent == null || (!parent.exists() && !parent.mkdirs())) {
String msg = "Unable to create directory " + parent;
if (parent == null) {
msg = "Unable to create directory, File.getParentFile() returns null: " + out.getPath();
}
StringTreeLeaf reason = new StringTreeLeaf(this,
false,
msg);
if (firstDirectoryCreationError) {
// this is probably something the user wants to see, at least once
firstDirectoryCreationError = false;
System.err.println("WARNING: "+reason.toString());
}
return reason;
}
return new Pass(this);
}
public void removeExisting(CacheEvent event,
ChannelImpl channel,
LocalSeismogramImpl representativeSeismogram, int numSeismograms) {
for(int i = 0; true; i++) {
File cur = new File(generate(event, channel, representativeSeismogram, i, numSeismograms));
if(!cur.exists()) {
break;
}
cur.delete();
}
}
public void removeExisting(CacheEvent event,
ChannelImpl channel,
ChannelImpl otherChannel,
Map<String, Object> extras) {
for(int i = 0; true; i++) {
File cur = new File(generate(event, channel, otherChannel, i, extras));
if(!cur.exists()) {
break;
}
cur.delete();
}
}
public void removeExisting(CacheEvent event,
ChannelGroup channelGroup,
Map<String, Object> extras) {
for(int i = 0; true; i++) {
File cur = new File(generate(event, channelGroup, i, extras));
if(!cur.exists()) {
break;
}
cur.delete();
}
}
public static final String DEFAULT_FILE_TEMPLATE_WO_EXT = "Event_${event.getTime('yyyy_MM_dd_HH_mm_ss')}/${prefix}${channel.codes}${index}";
public static final String DEFAULT_PREFIX = "";
public static final String DEFAULT_WORKING_DIR = "seismograms/";
protected String workingDir;
protected String origTemplate;
protected String template;
protected String prefix;
protected SimpleVelocitizer velocitizer = new SimpleVelocitizer();
public String getTemplate() {
return template;
}
protected static String extractFileTemplate(Element el, String def) {
return DOMHelper.extractText(el, "location", def);
}
protected static String extractPrefix(Element el) {
return DOMHelper.extractText(el, "prefix", DEFAULT_PREFIX);
}
public static String extractWorkingDir(Element el) {
return DOMHelper.extractText(el, "workingDir", DEFAULT_WORKING_DIR, true);
}
protected static final Pattern INDEX_VAR = Pattern.compile(".*\\$\\{?index\\}?.*");
public AbstractFileWriter() {
super();
}
boolean firstDirectoryCreationError = true;
}