001 /* 002 * mesopotamia @mesopotamia.version@ 003 * Multilingual parser and repository. 004 * Copyright (C) 2005 Hammurapi Group 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2 of the License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 019 * 020 * URL: http://http://www.hammurapi.biz 021 * e-Mail: support@hammurapi.biz 022 */ 023 package org.mesopotamia.util; 024 025 import java.util.ArrayList; 026 import java.util.Collection; 027 import java.util.HashSet; 028 import java.util.Set; 029 import java.util.logging.Logger; 030 031 import antlr.collections.AST; 032 import biz.hammurapi.util.CollectionVisitable; 033 import biz.hammurapi.util.VisitableBase; 034 import biz.hammurapi.util.Visitor; 035 036 037 public class RuleDefinition extends VisitableBase { 038 private static final Logger logger = Logger.getLogger(RuleDefinition.class.getName()); 039 040 private BnfModel model; 041 private String name; 042 private Set<Object> matchPaths=new HashSet<Object>(); 043 private Collection<Attribute> attributes=new ArrayList<Attribute>(); 044 private boolean isInterface; 045 private boolean isFactory; 046 047 private String rootLanguageElementClassName; 048 049 RuleDefinition(BnfModel model, AST node, String rootLanguageElementClassName) { 050 this.model=model; 051 this.rootLanguageElementClassName = rootLanguageElementClassName; 052 name=node.getText(); 053 for (AST child=node.getFirstChild(); child!=null; child=child.getNextSibling()) { 054 switch (child.getType()) { 055 case BnfTokenTypes.LITERAL_interface: 056 isInterface=true; 057 break; 058 case BnfTokenTypes.LITERAL_factory: 059 isFactory=true; 060 break; 061 case BnfTokenTypes.SUBTYPE: 062 if (isInterface()) { 063 model.addInterface(child.getText(), this); 064 } else { 065 RuleDefinition alreadyDefined = model.superClasses.get(child.getText()); 066 if (alreadyDefined==null) { 067 model.superClasses.put(child.getText(), this); 068 } else { 069 logger.warning("Superclass already defined: "+child.getText()+" extends "+alreadyDefined.getName()+", new superclass: "+node.getText()); 070 } 071 } 072 break; 073 case BnfTokenTypes.CPATH: 074 MatchPath path=new MatchPath(this, child); 075 matchPaths.add(path); 076 if (model.matchPath.put(path, this)!=null) { 077 logger.warning(child.getLine()+":"+child.getColumn()+" Duplicate match path"); 078 } 079 break; 080 case BnfTokenTypes.ATTRIBUTE: 081 attributes.add(new Attribute(this, child, model.getPackage())); 082 break; 083 default: 084 throw new IllegalArgumentException("Unexpected node: "+BnfRecognizer._tokenNames[child.getType()]+" at "+child.getLine()+":"+child.getColumn()); 085 086 } 087 } 088 089 // Store paths in the model, validation - same match expression for more than one rule 090 091 } 092 093 public String getName() { 094 return name; 095 } 096 097 public String toString() { 098 return getName() + (isInterface() ? "" : " extends " + getSuperClassName()) + (getImplements().isEmpty() ? "" : " implements " + getImplements()); 099 } 100 101 public boolean isInterface() { 102 return isInterface; 103 } 104 105 public boolean isFactory() { 106 return isFactory; 107 } 108 109 public String getSuperClassName() { 110 RuleDefinition superRule = getSuperRule(); 111 return isInterface() ? "" : superRule==null ? rootLanguageElementClassName : superRule.getName(); 112 } 113 114 /** 115 * @return 116 */ 117 public RuleDefinition getSuperRule() { 118 RuleDefinition superRule=model.superClasses.get(this.getName()); 119 return superRule; 120 } 121 122 public Collection<String> getImplements() { 123 Collection<String> ret=new ArrayList<String>(); 124 Collection<RuleDefinition> interfaces=model.interfaces.get(getName()); 125 if (interfaces!=null) { 126 for (RuleDefinition i: interfaces) { 127 ret.add(i.getName()); 128 } 129 } 130 return ret; 131 } 132 133 protected Set<Object> getMatchPaths() { 134 return matchPaths; 135 } 136 137 public BnfModel getModel() { 138 return model; 139 } 140 141 protected void acceptChildren(Visitor visitor) { 142 new CollectionVisitable(matchPaths, false).accept(visitor); 143 } 144 145 public Collection<Attribute> getAttributes() { 146 return attributes; 147 } 148 149 public String getFullClassName() { 150 return name.indexOf('.')==-1 ? model.getPackage()+"."+name : name; 151 } 152 }