package org.glassfish.pfl.basic.tools.logex;
import org.glassfish.pfl.basic.tools.argparser.ArgParser;
import org.glassfish.pfl.basic.tools.argparser.DefaultValue;
import org.glassfish.pfl.basic.tools.argparser.Help;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.glassfish.pfl.basic.tools.file.FileWrapper;
import org.glassfish.pfl.basic.tools.file.Scanner;
import org.glassfish.pfl.basic.logex.ExceptionWrapper;
import org.glassfish.pfl.basic.logex.WrapperGenerator;
public class ExceptionResourceGenerator {
private final Arguments args ;
private ExceptionResourceGenerator( String[] strs ) throws IOException {
ArgParser ap = new ArgParser( Arguments.class ) ;
args = ap.parse( strs, Arguments.class ) ;
args.destination().delete() ;
}
private interface Arguments {
@Help( "Set to >0 to get information about actions taken for every "
+ "file. Larger values give more detail." )
@DefaultValue( "0" )
int verbose() ;
@Help( "Source directory for classes to scan" )
@DefaultValue( "" )
File source() ;
@Help( "Destination file for resources" )
@DefaultValue( "" )
File destination() ;
}
private void msg(String string) {
System.out.println( string ) ;
}
private static String getLoggerName( Class<?> cls ) {
ExceptionWrapper ew = cls.getAnnotation( ExceptionWrapper.class ) ;
String str = ew.loggerName() ;
if (str.length() == 0) {
str = cls.getPackage().getName() ;
}
return str ;
}
public static List<String> getResources( final Class<?> cls ) {
if (cls.getAnnotation( ExceptionWrapper.class ) == null) {
throw new RuntimeException( cls
+ " does not have an @ExceptionWrapper annotation") ;
}
Field self ;
try {
self = cls.getDeclaredField("self");
} catch (Exception ex) {
throw new RuntimeException("Could not get field named self in "
+ cls, ex) ;
}
int mod = self.getModifiers() ;
if (!Modifier.isStatic(mod) || !Modifier.isPublic(mod)) {
throw new RuntimeException( cls + " is not public static") ;
}
if (!self.getType().equals(cls)) {
throw new RuntimeException( cls.getName()
+ ".self does not have the correct type" ) ;
}
WrapperGenerator.MessageInfo minfo ;
try {
minfo = (WrapperGenerator.MessageInfo)self.get(null) ;
} catch (Exception exc) {
throw new RuntimeException( "Could not access field self in " + cls,
exc ) ;
}
Map<String,String> mmap = minfo.getMessageInfo() ;
final List<String> result = new ArrayList<String>() ;
for (Map.Entry<String,String> entry : mmap.entrySet()) {
final StringBuilder sb = new StringBuilder() ;
sb.append( entry.getKey() ) ;
sb.append( "=\"" ) ;
sb.append( entry.getValue() ) ;
sb.append( "\"" ) ;
result.add( sb.toString() ) ;
}
return result ;
}
Scanner.Action action = new Scanner.Action() {
@SuppressWarnings("unchecked")
@Override
public boolean evaluate(FileWrapper arg) {
String fileName = arg.getAbsoluteName() ;
if (fileName.endsWith(".class")) {
final String absSourceName = args.source().getAbsolutePath() ;
final String relArgName = fileName.substring(
absSourceName.length() + 1,
fileName.length() - ".class".length() ) ;
final File output = new File( args.destination(),
relArgName + ".properties" ) ;
final FileWrapper dest = new FileWrapper( output ) ;
final String className =
relArgName.replace( File.separatorChar, '.' );
ExceptionWrapper ew = null ;
try {
Class cls = Class.forName( className ) ;
ew = (ExceptionWrapper)cls.getAnnotation(
ExceptionWrapper.class) ;
if (ew != null) {
if (args.verbose() > 0) {
msg( "Writing resource file for class "
+ cls.getName() ) ;
}
List<String> resStrings = getResources(cls) ;
dest.open(FileWrapper.OpenMode.WRITE_EMPTY);
dest.writeLine( "### Resource file generated on "
+ new Date() ) ;
dest.writeLine( "#" ) ;
dest.writeLine( "# Resources for class " + className );
dest.writeLine( "#" ) ;
if (resStrings != null) {
for (String str : resStrings) {
dest.writeLine(str);
}
}
}
} catch (Exception exc ) {
if (args.verbose() > 0) {
msg( "Error in processing class " + className ) ;
exc.printStackTrace();
}
} finally {
if (ew != null) {
dest.close();
}
}
}
return true ;
}
} ;
private void run() throws IOException {
Scanner scanner = new Scanner( args.verbose(), args.source() ) ;
scanner.scan(action);
}
public static void main( String[] strs ) throws IOException {
(new ExceptionResourceGenerator(strs)).run() ;
}
}