package org.kohsuke.bali.writer;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Writer;
import org.kohsuke.bali.datatype.DatatypeImpl;
import org.kohsuke.bali.datatype.Value;
/**
* Generate C# source code.
*
* @author Kohsuke Kawaguchi (kk@kohsuke.org)
*/
public class CSharpWriter extends StringBasedEncoder {
private final PrintWriter out;
private final String packageName;
private final String className;
private final File outDir;
/**
* @param _packageName
* package name or null to put the code into the root package.
*/
public CSharpWriter( String _packageName, String _className, File _outDir ) throws IOException {
this.packageName = _packageName;
this.className = _className;
this.out = new PrintWriter(new FileWriter(new File(_outDir,className+".cs")));
this.outDir = _outDir;
}
protected void write(
String encNameCodes,
int defaultNameCode,
String encStates,
String encATr,
String encDTr,
String encETr,
String encITr,
String encLTr,
String encNTr,
String encVTr,
DatatypeImpl[] datatypes,
Value[] values)
throws IOException {
out.println("// GENERATED CODE --- DO NOT MODIFY");
out.println();
out.println("using System;");
out.println("using System.Xml;");
out.println("using org.relaxng.datatype;");
// out.println("using Org.Kohsuke.Bali");
out.println();
if( packageName!=null ) {
out.println("namespace "+packageName);
out.println("{");
}
out.println("public class "+className+" : DomValidatelet");
out.println("{");
out.println(TAB+"///<summary>");
out.println(TAB+"///Create a new instance of <c>Validatelet</c> preconfigured for this schema.");
out.println(TAB+"///</summary>");
out.println(TAB+"public "+className+"() : base("+className+".Schema) {}");
out.println();
out.println();
out.println(TAB+"///<summary>");
out.println(TAB+"///Default instance of the compiled schema.");
out.println(TAB+"///Compiled with default datatype libraries.");
out.println(TAB+"///</summary>");
out.println(TAB+"public static readonly Schema Schema = CreateSchema();");
out.println();
out.println();
out.println(TAB+"///<summary>");
out.println(TAB+"///Main method for quick testing");
out.println(TAB+"///</summary>");
out.println(TAB+"public static int Main( string[] args ) {");
out.println(TAB+TAB+"XmlDocument dom = new XmlDocument();");
out.println(TAB+TAB+"dom.PreserveWhitespace = true;");
out.println(TAB+TAB+"DomValidatelet validatelet = new "+className+"();");
out.println(TAB+TAB+"try {");
out.println(TAB+TAB+TAB+"foreach( string arg in args ) {");
out.println(TAB+TAB+TAB+TAB+"Console.WriteLine(\"validating \"+arg);");
out.println(TAB+TAB+TAB+TAB+"dom.Load(arg);");
out.println(TAB+TAB+TAB+TAB+"validatelet.Validate(dom);");
out.println(TAB+TAB+TAB+"}");
out.println(TAB+TAB+"} catch( DomValidationException e ) {");
out.println(TAB+TAB+TAB+"Console.WriteLine(e.Message);");
out.println(TAB+TAB+TAB+"return -1;");
out.println(TAB+TAB+"}");
out.println(TAB+TAB+"Console.WriteLine(\"validated\");");
out.println(TAB+TAB+"return 0;");
out.println(TAB+"}");
out.println();
out.println();
out.println(TAB+"///<summary>");
out.println(TAB+"///Obtain a compiled schema by using default datatype libraries.");
out.println(TAB+"///</summary>");
out.println(TAB+"public static Schema CreateSchema() {");
out.println(TAB+TAB+"return CreateSchema(new DefaultDatatypeLibraryLoader());");
out.println(TAB+"}");
out.println();
out.println();
out.println(TAB+"///<summary>");
out.println(TAB+"///Obtain a compiled schema by using a custom datatype library loader.");
out.println(TAB+"///</summary>");
out.println(TAB+"public static Schema CreateSchema( DatatypeLibraryFactory datatypeFactory) {");
out.println(TAB+TAB+"return new Schema(");
out.write(Util.toCSharpString(encNameCodes));
out.write("/*name literals*/,\n");
out.write(Integer.toString(defaultNameCode));
out.write("/*default name code*/,\n");
out.write(escape(encStates));
out.write("/*states*/,\n");
out.write(escape(encATr));
out.write("/*a-tr*/,\n");
out.write(escape(encDTr));
out.write("/*d-tr*/,\n");
out.write(escape(encETr));
out.write("/*e-tr*/,\n");
out.write(escape(encITr));
out.write("/*i-tr*/,\n");
out.write(escape(encLTr));
out.write("/*l-tr*/,\n");
out.write(escape(encNTr));
out.write("/*n-tr*/,\n");
out.write(escape(encVTr));
out.write("/*v-tr*/,\n");
out.write("new object[]{");
for( int i=0; i<datatypes.length; i++ ) {
if(i!=0) out.write(',');
out.write(encode(datatypes[i]));
}
out.write("}/*datatypes*/,\n");
out.write("new object[]{");
for( int i=0; i<values.length; i++ ) {
if(i!=0) out.write(',');
out.write(Util.toJavaString(values[i].value));
out.write(',');
out.write(encodeContext(values[i].context));
}
out.write("}/*values*/,\n");
out.println(TAB+TAB+"datatypeFactory);");
out.println(TAB+"}");
out.println("}");
if( packageName!=null )
out.println("}");
out.close();
copy("BaliRuntime.cs");
copy("DomValidatelet.cs");
}
/**
* Copies the resource file with the given file name to the target directory.
* Used to produce runtime code the target directory.
*/
private void copy( String fileName ) throws IOException {
BufferedReader reader = new BufferedReader( new InputStreamReader(
this.getClass().getResourceAsStream("/csharp/"+fileName) ));
PrintWriter writer = new PrintWriter(new FileWriter( new File( outDir, fileName ) ));
// copy the rest of the lines
String line;
while( (line=reader.readLine())!=null ) {
if( line.startsWith("namespace ") ) {
// replace it with the user-specified namespace
if( packageName==null )
continue;
else
line = "namespace "+packageName + " {";
}
if( line.startsWith("}//end namespace") && packageName==null )
continue; // skip the end mark if necessary
writer.println(line);
}
reader.close();
writer.close();
}
protected String escape(String str) {
return Util.toCSharpString(str);
}
private static final String TAB = "\t";
}