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 }