001    /*
002    @license.text@
003     */
004    package com.hammurapi.bnf2emf;
005    
006    import java.util.ArrayList;
007    import java.util.Collection;
008    import java.util.HashSet;
009    import java.util.Set;
010    import java.util.logging.Logger;
011    
012    import antlr.collections.AST;
013    
014    
015    public class RuleDefinition {
016            private static final Logger logger = Logger.getLogger(RuleDefinition.class.getName());
017            
018            private Bnf2Emf model;
019            private String name;
020            private Set<Object> matchPaths=new HashSet<Object>();
021            private Collection<Attribute> attributes=new ArrayList<Attribute>();
022            private boolean isInterface;
023            private boolean isFactory;
024    
025            private String rootLanguageElementClassName;
026    
027            RuleDefinition(Bnf2Emf model, AST node, String rootLanguageElementClassName) {
028                    this.model=model;
029                    this.rootLanguageElementClassName = rootLanguageElementClassName;
030                    name=node.getText();
031                    for (AST child=node.getFirstChild(); child!=null; child=child.getNextSibling()) {
032                            switch (child.getType()) {
033                                    case BnfTokenTypes.LITERAL_interface:
034                                            isInterface=true;
035                                            break;
036                                    case BnfTokenTypes.LITERAL_factory:
037                                            isFactory=true;
038                                            break;
039                                    case BnfTokenTypes.SUBTYPE:
040                                            if (isInterface()) {
041                                                    model.addInterface(child.getText(), this);
042                                            } else {
043                                                    RuleDefinition alreadyDefined = model.superClasses.get(child.getText());
044                                                    if (alreadyDefined==null) {
045                                                            model.superClasses.put(child.getText(), this);
046                                                    } else {
047                                                            logger.warning("Superclass already defined: "+child.getText()+" extends "+alreadyDefined.getName()+", new superclass: "+node.getText());
048                                                    }
049                                            }
050                                            break;
051                                    case BnfTokenTypes.ATTRIBUTE:
052                                            attributes.add(new Attribute(child));
053                                            break;
054                                    default:
055                                            throw new IllegalArgumentException("Unexpected node: "+BnfRecognizer._tokenNames[child.getType()]+" at "+child.getLine()+":"+child.getColumn());
056                                    
057                            }
058                    }
059                    
060                    // Store paths in the model, validation - same match expression for more than one rule
061                    
062            }
063            
064            public String getName() {
065                    return name;
066            }
067            
068            public String toString() {
069                    return getName() + (isInterface() ? "" : " extends " + getSuperClassName()) + (getImplements().isEmpty() ? "" : " implements " + getImplements());
070            }
071            
072            public boolean isInterface() {
073                    return isInterface;
074            }
075            
076            public boolean isFactory() {
077                    return isFactory;
078            }
079            
080            public String getSuperClassName() {
081                    RuleDefinition superRule = getSuperRule();
082                    return isInterface() ? "" : superRule==null ? rootLanguageElementClassName : superRule.getName();
083            }
084    
085            /**
086             * @return
087             */
088            public RuleDefinition getSuperRule() {
089                    RuleDefinition superRule=model.superClasses.get(this.getName());
090                    return superRule;
091            }
092            
093            public Collection<String> getImplements() {
094                    Collection<String> ret=new ArrayList<String>();
095                    Collection<RuleDefinition> interfaces=model.interfaces.get(getName());
096                    if (interfaces!=null) {
097                            for (RuleDefinition i: interfaces) {
098                                    ret.add(i.getName());
099                            }
100                    }
101                    return ret;
102            }
103    
104            protected Set<Object> getMatchPaths() {
105                    return matchPaths;
106            }
107            
108            public Bnf2Emf getModel() {
109                    return model;
110            }
111                    
112            public Collection<Attribute> getAttributes() {
113                    return attributes;
114            }
115            
116    }