alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

package bsh;

import java.io.*;
import java.util.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
	
	@author Pat Niemeyer (pat@pat.net)
*/
public class ClassGeneratorImpl extends ClassGenerator
{
	public Class generateClass( 
		String name, Modifiers modifiers, 
		Class [] interfaces, Class superClass, BSHBlock block, 
		boolean isInterface, CallStack callstack, Interpreter interpreter 
	)
		throws EvalError
	{
		// Delegate to the static method
		return generateClassImpl( name, modifiers, interfaces, superClass,
			block, isInterface, callstack, interpreter );
	}

	public Object invokeSuperclassMethod(
		BshClassManager bcm, Object instance, String methodName, Object [] args
	)
        throws UtilEvalError, ReflectError, InvocationTargetException
	{
		// Delegate to the static method
		return invokeSuperclassMethodImpl( bcm, instance, methodName, args );
	}

	/**
		Change the parent of the class instance namespace.
		This is currently used for inner class support.
		Note: This method will likely be removed in the future.
	*/
	// This could be static
	public void setInstanceNameSpaceParent( 
		Object instance, String className, NameSpace parent )
	{
		This ithis = 
			ClassGeneratorUtil.getClassInstanceThis( instance, className );
		ithis.getNameSpace().setParent( parent );
	}

	/**
		Parse the BSHBlock for for the class definition and generate the class
		using ClassGenerator.
	*/
	public static Class generateClassImpl( 
		String name, Modifiers modifiers, 
		Class [] interfaces, Class superClass, BSHBlock block, 
		boolean isInterface, CallStack callstack, Interpreter interpreter 
	)
		throws EvalError
	{
		// Scripting classes currently requires accessibility
		// This can be eliminated with a bit more work.
		Capabilities.setAccessibility( true );	
		if ( !Capabilities.haveAccessibility() )
			throw new InterpreterError(
				"Defining classes currently requires reflect Accessibility.");

		NameSpace enclosingNameSpace = callstack.top();
		String packageName = enclosingNameSpace.getPackage();
		String className =  enclosingNameSpace.isClass ?  
			( enclosingNameSpace.getName()+"$"+name ) : name;
		String fqClassName = 
			packageName == null ? className : packageName + "." + className;

		BshClassManager bcm = interpreter.getClassManager();
		// Race condition here...
		bcm.definingClass( fqClassName );

		// Create the class static namespace
		NameSpace classStaticNameSpace = 
			new NameSpace( enclosingNameSpace, className);
		classStaticNameSpace.isClass = true;

		callstack.push( classStaticNameSpace );

		// Evaluate any inner class class definitions in the block 
		// effectively recursively call this method for contained classes first
		block.evalBlock( 
			callstack, interpreter, true/*override*/, 
			ClassNodeFilter.CLASSCLASSES );

		// Generate the type for our class
		Variable [] variables = 
			getDeclaredVariables( block, callstack, interpreter, packageName );
		DelayedEvalBshMethod [] methods =
			getDeclaredMethods( block, callstack, interpreter, packageName );

		ClassGeneratorUtil classGenerator = new ClassGeneratorUtil( 
			modifiers, className, packageName, superClass, interfaces, 
			variables, methods, classStaticNameSpace, isInterface );
		byte [] code = classGenerator.generateClass();

		// if debug, write out the class file to debugClasses directory
		String dir = System.getProperty("debugClasses");
		if ( dir != null )
		try {
			FileOutputStream out= 
				new FileOutputStream( dir+"/"+className+".class" );
			out.write(code);
			out.close();
		} catch ( IOException e ) { }

		// Define the new class in the classloader
		Class genClass = bcm.defineClass( fqClassName, code );

//bcm.doneDefiningClass( fqClassName );

		// import the unq name into parent
		enclosingNameSpace.importClass( fqClassName.replace('$','.') );

		// Also cache the class so that no import resolution must occur
		// this avoids having to load our enclosing class which isn't
		// finished being generated yet... oy.

// caching is not correct and doesn't seem to help...
//	enclosingNameSpace.cacheClass( name, genClass );

// Also cache it in the static namespace...
//classStaticNameSpace.cacheClass( name, genClass );

//classStaticNameSpace.importClass( fqClassName.replace('$','.') );

		try {
			classStaticNameSpace.setLocalVariable( 
				ClassGeneratorUtil.BSHINIT, block, false/*strictJava*/ );
		} catch ( UtilEvalError e ) {
			throw new InterpreterError("unable to init static: "+e );
		}

		// Give the static space its class static import
		// important to do this after all classes are defined
		classStaticNameSpace.setClassStatic( genClass );

		// evaluate the static portion of the block in the static space
		block.evalBlock( 
			callstack, interpreter, true/*override*/, 
			ClassNodeFilter.CLASSSTATIC );

		callstack.pop();

		if ( !genClass.isInterface() )
		{
		// Set the static bsh This callback 
		String bshStaticFieldName = ClassGeneratorUtil.BSHSTATIC+className;
		try {
			LHS lhs = Reflect.getLHSStaticField( genClass, bshStaticFieldName );
			lhs.assign( 
				classStaticNameSpace.getThis( interpreter ), false/*strict*/ );
		} catch ( Exception e ) {
			throw new InterpreterError("Error in class gen setup: "+e );
		}
		}

		bcm.doneDefiningClass( fqClassName );
		return genClass;
	}

	static Variable [] getDeclaredVariables( 
		BSHBlock body, CallStack callstack, Interpreter interpreter, 
		String defaultPackage 
	) 
		throws EvalError
	{
		List vars = new ArrayList();
		for( int child=0; child
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.