From: Steve F. <sm...@us...> - 2003-06-21 14:01:10
|
Update of /cvsroot/mockobjects/mockobjects-java/src/core/com/mockobjects/tools In directory sc8-pr-cvs1:/tmp/cvs-serv11585/src/core/com/mockobjects/tools Added Files: Tag: Nat_reworks_dynamics_from_0_09 Boxer.java Log Message: Branched and added Nat's latest reworking of the dynamic libraries --- NEW FILE: Boxer.java --- /** Created on Jun 19, 2003 by npryce * Copyright (c) B13media Ltd. */ package com.mockobjects.tools; import java.io.FileWriter; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; public class Boxer { static final String INDENT1 = " "; static final String INDENT2 = INDENT1+INDENT1; static final Map BOXES = new HashMap(); static { BOXES.put( boolean.class, Boolean.class ); BOXES.put( byte.class, Byte.class ); BOXES.put( short.class, Short.class ); BOXES.put( int.class, Integer.class ); BOXES.put( long.class, Long.class ); BOXES.put( float.class, Float.class ); BOXES.put( double.class, Double.class ); BOXES.put( char.class, Character.class ); } static String nameOfClass( String className ) { int dotIndex = className.lastIndexOf('.'); if (dotIndex >= 0) { return className.substring(dotIndex + 1); } else { return className; } } static String packageOfClass( String className ) { int dotIndex = className.lastIndexOf('.'); if (dotIndex >= 0) { return className.substring(0, dotIndex); } else { return null; } } static boolean classHasPackage( String className ) { return className.lastIndexOf('.') > 0; } static boolean isPackageScope( int modifiers ) { return !Modifier.isPublic(modifiers) && !Modifier.isProtected(modifiers) && !Modifier.isPrivate(modifiers); } static String parameterName( int i ) { return "arg" + i; } static String typeSyntax( Class c ) { if( c.isPrimitive() ) { return c.toString(); } else if( c.isArray() ) { return typeSyntax(c.getComponentType()) + "[]"; } else { return c.getName(); } } static void generateFormalParameter( PrintWriter out, Class parameterType, int i ) { out.print( typeSyntax(parameterType) ); out.print( " " ); out.print( parameterName(i) ); } static void generateFormalParameters( PrintWriter out, Class[] parameterTypes ) { out.print("("); for( int i = 0; i < parameterTypes.length; i++ ) { if( i > 0 ) out.print( ", "); generateFormalParameter( out, parameterTypes[i], i ); } out.print(")"); } static void generateThrowsClause( PrintWriter out, Class[] exceptionTypes ) { if( exceptionTypes.length > 0 ) { out.print(" throws "); for( int i = 0; i < exceptionTypes.length; i++ ) { if( i > 0 ) out.print(", "); out.print( exceptionTypes[i].getName() ); } } } static void generateActualParameters( PrintWriter out, Class[] parameterTypes ) { for( int i = 0; i < parameterTypes.length; i++ ) { if( i > 0 ) out.print(", "); out.print( parameterName(i) ); } } static void generateSuperConstructorCall( PrintWriter out, Constructor c ) { out.print(INDENT2); out.print("super("); generateActualParameters( out, c.getParameterTypes() ); out.println(");"); } static void generateConstructor( PrintWriter out, Constructor c, String className ) { out.print(INDENT1); out.print("public "); out.print(nameOfClass(className)); generateFormalParameters( out, c.getParameterTypes() ); generateThrowsClause( out, c.getExceptionTypes() ); out.println( " {" ); generateSuperConstructorCall( out, c ); out.print(INDENT1); out.println("}"); } static void generateConstructors( PrintWriter out, Class template, String className ) { Constructor[] constructors = template.getDeclaredConstructors(); boolean canCallPackageMethods = template.getPackage().getName().equals( packageOfClass(className) ); for( int i = 0; i < constructors.length; i++ ) { Constructor c = constructors[i]; if( Modifier.isProtected(c.getModifiers()) || Modifier.isPublic(c.getModifiers()) || (isPackageScope(c.getModifiers()) && canCallPackageMethods) ) { if( i > 0 ) out.println(); generateConstructor( out, c, className ); } } } static List expandOverloadsForParameter( List overloads, int parameterIndex ) { List expandedOverloads = new ArrayList(); for( Iterator oi = overloads.iterator(); oi.hasNext(); ) { Class[] arguments = (Class[])oi.next(); for( Iterator bi = BOXES.keySet().iterator(); bi.hasNext(); ) { Class primitiveType = (Class)bi.next(); Class[] overloadedArguments = (Class[])arguments.clone(); overloadedArguments[parameterIndex] = primitiveType; expandedOverloads.add(overloadedArguments); } } return expandedOverloads; } static List listOverloadsForMethod( Class[] parameterTypes ) { List overloads = new ArrayList(); overloads.add(parameterTypes); for( int i = 0; i < parameterTypes.length; i++ ) { if( parameterShouldBeBoxed(parameterTypes[i]) ) { overloads = expandOverloadsForParameter( overloads, i ); } } return overloads; } static void generateBoxExpression( PrintWriter out, Class primitiveType, String parameterName ) { Class boxClass = (Class)BOXES.get(primitiveType); out.print( "new " ); out.print( nameOfClass(boxClass.getName()) ); out.print( "(" ); out.print( parameterName ); out.print( ")" ); } static void generateSuperCallForOverloadedMethod( PrintWriter out, Method m, Class[] overloadedParameterTypes ) { Class[] originalParameterTypes = m.getParameterTypes(); out.print(INDENT2); out.print("super."); out.print(m.getName()); out.print("("); for( int i = 0; i < originalParameterTypes.length; i++ ) { if( i > 0 ) out.print(", "); if( parameterShouldBeBoxed(originalParameterTypes[i]) ) { generateBoxExpression( out, overloadedParameterTypes[i], parameterName(i) ); } else { out.print( parameterName(i) ); } } out.println(");"); } static boolean parameterShouldBeBoxed( Class type ) { return type == Object.class; } static void generateOverloadedMethod( PrintWriter out, Method m, Class[] overloadedParameterTypes ) { out.print(INDENT1); out.print("public "); out.print(m.getReturnType()); out.print(" "); out.print(m.getName()); generateFormalParameters( out, overloadedParameterTypes ); generateThrowsClause( out, m.getExceptionTypes() ); out.println(" {"); generateSuperCallForOverloadedMethod( out, m, overloadedParameterTypes ); out.print(INDENT1); out.println("}"); } static void generateOverloadsForMethod( PrintWriter out, Method m ) { List overloads = listOverloadsForMethod( m.getParameterTypes() ); if( overloads.size() > 1 ) { for( Iterator i = overloads.iterator(); i.hasNext(); ) { out.println(); generateOverloadedMethod( out, m, (Class[])i.next() ); } } } static void generateBoxerMethods( PrintWriter out, Class template ) { Method[] methods = template.getDeclaredMethods(); for( int i = 0; i < methods.length; i++ ) { Method m = methods[i]; if( Modifier.isPublic(m.getModifiers()) ) { generateOverloadsForMethod( out, m ); } } } static void generateBoxerClass( PrintWriter out, Class template, String className ) { out.println( "// WARNING: DO NOT EDIT" ); out.println( "// This file was automatically generated by the Boxer " + "(floats like a butterfly, strings like a bee)" ); out.println( "// Generated on " + (new Date()) ); out.println(); if( classHasPackage(className) ) { out.println( "package " + packageOfClass(className) + ";" ); out.println(); } out.print("public class "); out.print( nameOfClass(className) ); out.print(" extends "); out.print( template.getName() ); out.println( " {" ); generateConstructors( out, template, className ); generateBoxerMethods( out, template ); out.println( "}" ); } public static void main(String[] args) { if( args.length < 2 || args.length > 3 ) { System.err.println( "usage: java " + Boxer.class + " <template-class> <generated-class> [<output-file>]" ); System.exit(1); } try { Class templateClass = Class.forName( args[0] ); String generatedClassName = args[1]; PrintWriter out; if( args.length == 3 ) { out = new PrintWriter(new FileWriter(args[2])); } else { out = new PrintWriter(System.out); } generateBoxerClass( out, templateClass, generatedClassName ); out.flush(); if( args.length == 3 ) { System.out.println( "generated " + generatedClassName + " in file " + args[2] ); out.close(); } } catch( Exception ex ) { ex.printStackTrace(); System.exit(2); } } } |