001 /* 002 @license.text@ 003 */ 004 package biz.hammurapi.codegen; 005 006 import java.util.ArrayList; 007 import java.util.Collection; 008 import java.util.HashSet; 009 import java.util.Properties; 010 import java.util.Set; 011 012 import org.apache.bcel.generic.ClassGen; 013 014 import biz.hammurapi.codegen.JavaTokenTypes; 015 016 import antlr.collections.AST; 017 018 019 /** 020 * @author Pavel Vlasov 021 * @version $Revision: 1.5 $ 022 */ 023 public class Class extends ClassGeneratorBase { 024 /** 025 * 026 * @param definition E.g. <CODE>public class C extends a.b.A implements a.b.c.d.B</CODE> Superinterfaces names shall be fully qualified. 027 * @param description 028 * @param listener 029 * @throws GenerationException 030 */ 031 public Class(String definition, String description, GenerationListener listener) throws GenerationException { 032 this.listener=listener; 033 AST ast=typeDefinition(definition); 034 if (ast.getType()==JavaTokenTypes.CLASS_DEF) { 035 Set modifiers=new HashSet(); 036 String name=null; 037 String superClass="java.lang.Object"; 038 Collection implementedInterfaces=new ArrayList(); 039 for (AST node=ast.getFirstChild(); node!=null; node=node.getNextSibling()) { 040 switch (node.getType()) { 041 case JavaTokenTypes.MODIFIERS: 042 for (AST child=node.getFirstChild(); child!=null; child=child.getNextSibling()) { 043 modifiers.add(child.getText()); 044 } 045 break; 046 case JavaTokenTypes.IDENT: 047 name=node.getText(); 048 break; 049 case JavaTokenTypes.DOT: 050 name=toString(node); 051 break; 052 case JavaTokenTypes.EXTENDS_CLAUSE: 053 if (node.getFirstChild()!=null) { 054 superClass=toString(node.getFirstChild()); 055 } 056 break; 057 case JavaTokenTypes.IMPLEMENTS_CLAUSE: 058 for (AST interfaceNode=node.getFirstChild(); interfaceNode!=null; interfaceNode=interfaceNode.getNextSibling()) { 059 implementedInterfaces.add(toString(interfaceNode)); 060 } 061 break; 062 default: 063 throw new GenerationException("Unexpected node: "+node+" in '"+definition+"'"); 064 } 065 } 066 067 cg = new ClassGen( 068 name, 069 superClass, 070 description==null ? "<generated>" : description, 071 modifiers(modifiers), 072 (String[]) implementedInterfaces.toArray(new String[implementedInterfaces.size()])); 073 074 if (listener!=null && (modifiers.contains("protected") || modifiers.contains("public"))) { 075 listener.onClass(cg, description); 076 } 077 } else { 078 throw new GenerationException("Invalid node type "+ast.getType()+" in definition '"+definition+"'"); 079 } 080 } 081 082 /** 083 * Creates a private field of specified name and type. 084 * @param name 085 * @param type 086 * @param description 087 * @param attributes 088 * @throws GenerationException 089 */ 090 public void addField(String name, String type, String description, Properties attributes) throws GenerationException { 091 addField("private "+type+" "+name, description, attributes); 092 } 093 }