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 }