package beast.app.seqgen;

import java.io.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import beast.app.beauti.BeautiDoc;
import beast.core.*;
import beast.core.Input.*;
import beast.evolution.alignment.*;
import beast.util.*;

@Description("Helper for SequenceSimulator")
public class MergeDataWith extends BEASTObject {
	public Input<String> templateFileInput = new Input<String>("template","name of template file. " +
			"The template file should be a valid beast2 XML file with a single (possibly empty) alignment. " +
			"This alignment will be replaced by the alignment generated by the SequenceSimulator. " +
			"Any occurrance of $(n) will be replaced by the iteration number of the SequenceSimulator. " +
			"For example, calling a log filename \"output$(n).log\" will be replaced by " +
			"\"output1.log\" at first iteration, \"output2.log\" at seccond iteration, etc..", Validate.REQUIRED);
	public Input<String> outputFileInput = new Input<String>("output","name of the output file. " +
			"Instances of $(n) are replaced by iteration number.", Validate.REQUIRED);

	File templateFile;
	
	@Override
	public void initAndValidate() throws Exception {
		templateFile = new File(templateFileInput.get());
		if (!(templateFile.exists())) {
			throw new RuntimeException("Template file " + templateFileInput.get() + " does not exist"); 
		}
	} // initAndValidate
	
	
	void process(Alignment data, int iteration) throws Exception {
		// read template
		String templateXML = BeautiDoc.load(templateFile);
		templateXML = templateXML.replaceAll("\\$\\(n\\)", iteration+"");
		XMLParser parser = new XMLParser();
		BEASTObject b = parser.parseBareFragment(templateXML, false);

		// repalce alignment
		Alignment a = getAlignment(b);
		List<Sequence> sequences = a.sequenceInput.get();
		sequences.clear();
		sequences.addAll(data.sequenceInput.get());

		// write file
		String outputFile = outputFileInput.get();
		outputFile = outputFile.replaceAll("\\$\\(n\\)", iteration+"");
		FileWriter outfile = new FileWriter(outputFile);
		
		Set<BEASTObject> plugins = new HashSet<BEASTObject>();
		String sXML = new XMLProducer().toXML(b, plugins);
        outfile.write(sXML);
        outfile.close();
	} // process


	private Alignment getAlignment(BEASTObject b) throws IllegalArgumentException, IllegalAccessException {
		Alignment a = null;
		for (BEASTObject i : b.listActivePlugins()) {
			if (i.getClass().equals(Alignment.class)){
				return (Alignment) i;
			} else {
				a = getAlignment(i);
				if (a != null) {
					return a;
				}
			}
		}
		return null;
	} // getAlignment
	
}

package beast.app.seqgen;

import java.io.*;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import beast.app.beauti.BeautiDoc;
import beast.core.*;
import beast.core.Input.*;
import beast.evolution.alignment.*;
import beast.util.*;

@Description("Helper for Sequence Simulator, allows specifying template input file and destination output file")
public class MergeDataWith extends BEASTObject {
	public Input<String> templateFileInput = new Input<String>("template","name of template file. " +
			"The template file should be a valid beast2 XML file with a single (possibly empty) alignment. " +
			"This alignment will be replaced by the alignment generated by the SequenceSimulator. " +
			"Any occurrance of $(n) will be replaced by the iteration number of the SequenceSimulator. " +
			"For example, calling a log filename \"output$(n).log\" will be replaced by " +
			"\"output1.log\" at first iteration, \"output2.log\" at seccond iteration, etc..", Validate.REQUIRED);
	public Input<String> outputFileInput = new Input<String>("output","name of the output file. " +
			"Instances of $(n) are replaced by iteration number.", Validate.REQUIRED);

	File templateFile;
	
	@Override
	public void initAndValidate() throws Exception {
		templateFile = new File(templateFileInput.get());
		if (!(templateFile.exists())) {
			throw new RuntimeException("Template file " + templateFileInput.get() + " does not exist"); 
		}
	} // initAndValidate
	
	
	void process(Alignment data, int iteration) throws Exception {
		// read template
		String templateXML = BeautiDoc.load(templateFile);
		templateXML = templateXML.replaceAll("\\$\\(n\\)", iteration+"");
		XMLParser parser = new XMLParser();
		BEASTObject b = parser.parseBareFragment(templateXML, false);

		// repalce alignment
		Alignment a = getAlignment(b);
		List<Sequence> sequences = a.sequenceInput.get();
		sequences.clear();
		sequences.addAll(data.sequenceInput.get());

		// write file
		String outputFile = outputFileInput.get();
		outputFile = outputFile.replaceAll("\\$\\(n\\)", iteration+"");
		FileWriter outfile = new FileWriter(outputFile);
		
		Set<BEASTObject> plugins = new HashSet<BEASTObject>();
		String sXML = new XMLProducer().toXML(b, plugins);
        outfile.write(sXML);
        outfile.close();
	} // process


	private Alignment getAlignment(BEASTObject b) throws IllegalArgumentException, IllegalAccessException {
		Alignment a = null;
		for (BEASTObject i : b.listActivePlugins()) {
			if (i.getClass().equals(Alignment.class)){
				return (Alignment) i;
			} else {
				a = getAlignment(i);
				if (a != null) {
					return a;
				}
			}
		}
		return null;
	} // getAlignment
	
}

update description