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    }