package commons.cmd;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import basics.filesystem.file.FileUtl;
import basics.unexpected.Failure;
import basics.utl.SysUtl;
import commons.application.core.Command;
import commons.utl.CtxUtl;
public class xmltransform extends Command
{

private static final String MUSTHAVE = "input,output,xsl";
private static final String ARGS     = "ARGS: input:<xml-source-file>;output:<target-file>;xsl:<xsl-tranformation-file>. ";

public xmltransform()
{
   super();
}

//public xmltransform(String forerunner, String follower)
//{
//   super(forerunner, follower);
//}

public void process () throws Exception
{
   String source = ctx.consume("input", "");
   String target = ctx.getr("output", "");
   String template = ctx.getr("xsl", "");
   // the caller can send source and target as absolute
   // or relative path. For relative path we add
   // the home path to get a absolute path:
//   String home = CtxUtl.userHome(ctx);
//   if (!SU.contains(source, home))
//   {
//      source = FileUtl.concat(home, source);
//   }
//   if (!SU.contains(target, home))
//   {
//      target = FileUtl.concat(home, target);
//   }
   // String scripts = CtxUtl.scriptSpace (ctx).getAbsolutePath();
   template = FileUtl.concat(CtxUtl.scriptSpace(ctx).getAbsolutePath(), template);
   String sourceUrl = FileUtl.toStandardUrl(source);
   String targetUrl = FileUtl.toStandardUrl(target);
   String templateUrl = FileUtl.toStandardUrl(template);
   if (isDebugLevel(1)) SysUtl.trace("xslt(" + templateUrl + ")\ninput(" + sourceUrl + "\noutput(" + targetUrl + ")");
   if (source.equalsIgnoreCase(targetUrl)) throw new Failure("Source and target must be different: " + sourceUrl);
   // if (!new File(templateUrl).exists()) throw new Failure("No such template:
   // " +
   // templateUrl);
   Source xsltSource = new StreamSource(new FileInputStream(FileUtl.toFilePath(templateUrl)));
   Source xmlSource = new StreamSource(new FileInputStream(FileUtl.toFilePath(sourceUrl)));
   Result transResult = new StreamResult(new FileOutputStream(FileUtl.toFilePath(targetUrl)));
   TransformerFactory tf = TransformerFactory.newInstance();
   Transformer trans = tf.newTransformer(xsltSource);
   trans.transform(xmlSource, transResult);
}

public void signContract ()
{
   super.demand(MUSTHAVE, null);
}

public String description ()
{
   return implName() + " transforms a xml source using a xsl template and writes the result into a target. " + ARGS;
}
}
