package com.jaivox.tools;
import java.io.*;
import java.util.*;
import com.jaivox.util.Log;
/**
* The Generator creates all the files for an application, based on
* specifications. It also uses several templates and common files
* located in the common directory (you can specify the location of the
* common files in the configuration file.)
*/
public class Generator {
static Properties kv;
Set <String> keys;
String source = "./";
String common = "./";
String destination = "./";
String dir_recognizer;
String dir_interpreter;
String dir_synthesizer;
boolean onedir = false;
boolean overwrite = false;
static String templates [] = {
"interpreterTest.java",
"recognizerTest.java",
"project.config.xml",
"lmgen.sh",
"runinter.sh",
"runsphinx.sh",
"CxxServer.cc",
"CxxResponder.cc",
"CxxSession.cc"
};
String lmtool = "lmgen.sh";
String runsphinx = "runsphinx.sh";
String runinter = "runinter.sh";
/**
* Generate files based on a configuration file
@param confname
*/
public Generator (String confname) {
new Config (confname);
kv = Config.kv;
keys = kv.stringPropertyNames ();
String overwrite_answer = kv.getProperty ("overwrite_files");
if (overwrite_answer != null) {
if (overwrite_answer.equals ("yes")) overwrite = true;
}
String useonedir = kv.getProperty ("onedirectory");
if (useonedir != null) {
if (useonedir.equals ("yes")) onedir = true;
}
String src = kv.getProperty ("source");
if (src != null && !src.equals ("null")) source = src;
String cmn = kv.getProperty ("common");
if (cmn != null) common = cmn;
String dest = kv.getProperty ("destination");
if (dest != null) destination = dest;
if (onedir) {
dir_interpreter = destination;
dir_recognizer = destination;
dir_synthesizer = destination;
}
else {
dir_interpreter = destination + kv.getProperty ("dir_interpreter") + "/";
dir_recognizer = destination + kv.getProperty ("dir_recognizer") + "/";
dir_synthesizer = destination + kv.getProperty ("dir_synthesizer") + "/";
}
}
/**
* generate everything, i.e. speech, festival and interpreter agents,
* and files required by these agents.
*/
public void generateAll () {
boolean ok = false;
try {
// File src = new File (source);
File src = new File (common);
File fd = new File (destination);
if (!fd.exists ()) fd.mkdirs ();
if (!onedir) {
fd = new File (dir_interpreter);
if (!fd.exists ()) fd.mkdirs ();
fd = new File (dir_recognizer);
if (!fd.exists ()) fd.mkdirs ();
fd = new File (dir_synthesizer);
if (!fd.exists ()) fd.mkdirs ();
}
String files [] = src.list ();
Hashtable <String, String> tpls = new Hashtable <String, String> ();
String yes = "yes";
for (int i=0; i<templates.length; i++) {
String name = templates [i];
tpls.put (name, yes);
String dest = dir_interpreter;
if (name.endsWith (".cc")) dest = dir_synthesizer;
else if (name.endsWith (".h")) dest = dir_synthesizer;
else if (name.endsWith ("makefile")) dest = dir_synthesizer;
else if (name.startsWith ("recognizer") || name.endsWith (".config.xml") ||
name.equals (lmtool)) dest = dir_recognizer;
else if (name.equals (runsphinx)) dest = dir_recognizer;
else if (name.equals (runinter)) dest = dir_interpreter;
ok = generateFile (dest, name);
if (!ok) {
Log.severe ("Could not generate from "+name);
return;
}
}
for (int i=0; i<files.length; i++) {
String name = files [i];
if (tpls.get (name) != null) continue;
String dest = null;
if (name.endsWith (".cc")) dest = dir_synthesizer;
else if (name.endsWith (".h")) dest = dir_synthesizer;
else if (name.endsWith ("ccs.ccs")) dest = dir_recognizer;
else if (name.endsWith ("makefile")) dest = dir_synthesizer;
if (dest != null) {
if (!copyFile (common, dest, name)) {
Log.severe ("Could not copy "+name+" to "+destination);
return;
}
}
}
// copy specific files to interpreter
String datafile = kv.getProperty ("data_file");
if (!datafile.equals ("null") && !copyFile (source, dir_interpreter, datafile)) {
Log.severe ("Could not copy data file ");
return;
}
String commonwords = kv.getProperty ("common_words");
if (!copyFile (common, dir_interpreter, commonwords)) {
Log.severe ("Could not copy common words file");
return;
}
String answers = kv.getProperty ("answer_forms");
if (!copyFile (common, dir_interpreter, answers)) {
Log.severe ("Could not copy answer forms file");
return;
}
String specs = kv.getProperty ("specs_file");
if (!specs.equals ("null") && !copyFile (source, dir_interpreter, specs)) {
Log.severe ("Could not copy specifications file");
return;
}
String grammar = kv.getProperty ("grammar_file");
if (!grammar.equals ("null") && !copyFile (source, dir_interpreter, grammar)) {
Log.severe ("Could not copy grammar file ");
return;
}
}
catch (Exception e) {
e.printStackTrace ();
}
}
boolean generateFile (String dest, String name) {
try {
String filename = common + name;
String destname = dest + name;
if (!okOverwrite (destname)) {
Log.severe (destname+" exists. To overwrite, set overwrite_files to yes");
return true;
}
String text = loadFile (filename);
String changed = text;
for (Iterator<String> it = keys.iterator (); it.hasNext (); ) {
String key = it.next ();
String val = kv.getProperty (key);
if (name.startsWith (key)) {
String newname = name.replaceFirst (key, val);
// Log.fine ("Destination name: "+newname);
destname = dest + newname;
if (!okOverwrite (destname)) {
Log.severe (destname+" exists. To overwrite, set overwrite_files to yes");
return true;
}
}
String pat = "PAT"+key;
if (text.indexOf (pat) != -1) {
// Log.fine ("replacing "+pat+" with "+val+" in "+name);
changed = changed.replace (pat, val);
}
}
if (!writeFile (destname, changed)) return false;
Log.info ("wrote: "+destname);
return true;
}
catch (Exception e) {
e.printStackTrace ();
return false;
}
}
String loadFile (String filename) {
try {
BufferedReader in = new BufferedReader (new FileReader (filename));
String line;
StringBuffer sb = new StringBuffer ();
while ((line = in.readLine ()) != null) {
sb.append (line + "\n");
}
in.close ();
String text = new String (sb);
return text;
}
catch (Exception e) {
e.printStackTrace ();
return null;
}
}
boolean writeFile (String filename, String text) {
try {
PrintWriter out = new PrintWriter (new FileWriter (filename));
out.print (text);
out.close ();
return true;
}
catch (Exception e) {
e.printStackTrace ();
return false;
}
}
// easy way is to use jdk 1.7's java.nio.file
// import static java.nio.file.StandardCopyOption.*;
// Files.copy (source, target, REPLACE_EXISTING);
// http://docs.oracle.com/javase/tutorial/essential/io/copy.html
// will do it compatible with 1.6 here
boolean copyFile (String src, String dest, String filename) {
int bufsize = 1024;
try {
if (src == null) return false;
if (src.equals ("null")) return false;
String sourcefile = src + filename;
String destfile = dest + filename;
if (!okOverwrite (destfile)) {
Log.severe (destfile+" exists. To overwrite, set overwrite_files to yes");
return true;
}
FileInputStream in = new FileInputStream (sourcefile);
FileOutputStream out = new FileOutputStream (destfile);
byte buffer [] = new byte [bufsize];
int bytesread = 0;
while ((bytesread = in.read (buffer)) > 0) {
out.write (buffer, 0, bytesread);
}
in.close ();
out.close ();
Log.info ("Copied "+filename);
return true;
} catch (Exception e) {
e.printStackTrace ();
return false;
}
}
boolean okOverwrite (String filename) {
try {
File f = new File (filename);
if (f.exists ()) {
if (!overwrite) return false;
}
return true;
}
catch (Exception e) {
e.printStackTrace ();
return false;
}
}
/**
* create the questions from the give specifications
*/
public void createQuestions () {
Questgen qg = new Questgen (kv);
qg.generate ();
String textfile = kv.getProperty ("questions_file");
String resultfile = qg.datadir + textfile;
if (okOverwrite (resultfile)) qg.saveQuestions ();
String sentfile = kv.getProperty ("lm_training_file");
createLmQuestions (dir_interpreter, dir_recognizer,
textfile, sentfile);
}
/**
* Create only the things needed by the language model of the
* speech recognizer. This can be called to modify the language model
* after adding questions manually.
*/
public void updateLmQuestions () {
String textfile = kv.getProperty ("questions_file");
String sentfile = kv.getProperty ("lm_training_file");
createLmQuestions (dir_interpreter, dir_recognizer,
textfile, sentfile);
}
void createLmQuestions (String dirsrc, String dirtarget,
String textfile, String sentences) {
try {
String srcfile = dirsrc + textfile;
String destfile = dirtarget + sentences; // should give it a differnet name, later
String line;
BufferedReader in = new BufferedReader (new FileReader (srcfile));
PrintWriter out = new PrintWriter (new FileWriter (destfile));
while ((line = in.readLine ()) != null) {
String trim = line.trim ();
if (trim.length () == 0) continue;
int pos = trim.indexOf ("(");
if (pos == -1) continue;
String q = trim.substring (0, pos).trim ();
String upper = q.toUpperCase ();
out.println ("<s> " + upper + " </s>");
}
in.close ();
out.close ();
}
catch (Exception e) {
e.printStackTrace ();
}
}
};