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.Collection; 026 import java.util.Iterator; 027 028 import org.mesopotamia.MesopotamiaRuntimeException; 029 030 import antlr.collections.AST; 031 032 /** 033 * Parses attribute definition. 034 * 035 * @author Pavel Vlasov 036 * @revision $Revision$ 037 */ 038 public class Attribute { 039 private boolean isList; 040 private boolean isString; 041 private String name; 042 private String type; 043 private String path; 044 private String packageName; 045 private RuleDefinition owner; 046 047 public Attribute(RuleDefinition owner, AST node, String packageName) { 048 this.packageName=packageName; 049 this.owner=owner; 050 StringBuffer sb=new StringBuffer(); 051 for (AST child=node.getFirstChild(); child!=null; child=child.getNextSibling()) { 052 switch (child.getType()) { 053 case BnfTokenTypes.LITERAL_attribute: 054 isList=false; 055 isString=false; 056 break; 057 case BnfTokenTypes.LITERAL_list: 058 isList=true; 059 break; 060 case BnfTokenTypes.LITERAL_string: 061 isString=true; 062 break; 063 case BnfTokenTypes.IDENT: 064 case BnfTokenTypes.DOT: 065 StringBuffer nameBuf=new StringBuffer(); 066 typeName(child, nameBuf); 067 if (name==null) { 068 name=nameBuf.toString(); 069 type=name; 070 } else { 071 type=nameBuf.toString(); 072 } 073 break; 074 case BnfTokenTypes.PATH: 075 if (sb.length()>0) { 076 sb.append("|"); 077 } 078 StringBuffer peb=new StringBuffer(); 079 for (AST pe=child.getFirstChild(); pe!=null; pe=pe.getNextSibling()) { 080 if (peb.length()>0) { 081 peb.append("/"); 082 } 083 AST typeNode = pe.getFirstChild(); 084 switch (typeNode.getType()) { 085 case BnfTokenTypes.TYPE_REF: 086 peb.append("#"); 087 if (typeNode.getFirstChild().getType()==BnfTokenTypes.IDENT) { 088 peb.append(packageName); 089 peb.append("."); 090 } 091 typeName(typeNode.getFirstChild(), peb); 092 break; 093 case BnfTokenTypes.EXCL: 094 owner.getModel().checkTokenName(typeNode.getFirstChild().getText()); 095 peb.append("!"); 096 peb.append(typeNode.getFirstChild().getText()); 097 break; 098 case BnfTokenTypes.IDENT: 099 owner.getModel().checkTokenName(typeNode.getText()); 100 peb.append(typeNode.getText()); 101 break; 102 case BnfTokenTypes.STAR: 103 case BnfTokenTypes.DOUBLEDOT: 104 peb.append(typeNode.getText()); 105 break; 106 default: 107 throw new MesopotamiaRuntimeException("Unexpected token type: "+BnfRecognizer._tokenNames[typeNode.getType()]); 108 } 109 110 AST indexNode = typeNode.getNextSibling(); 111 if (indexNode!=null) { 112 peb.append("["); 113 peb.append(indexNode.getText()); 114 peb.append("]"); 115 } 116 } 117 sb.append(peb); 118 break; 119 default: 120 throw new IllegalArgumentException("Unexpected node type: "+BnfRecognizer._tokenNames[child.getType()]); 121 } 122 } 123 if (sb.length()!=0) { 124 path=sb.toString(); 125 } 126 } 127 128 static void typeName(AST node, StringBuffer sb) { 129 if (node.getType()==BnfTokenTypes.DOT) { 130 typeName(node.getFirstChild(), sb); 131 sb.append("."); 132 typeName(node.getFirstChild().getNextSibling(), sb); 133 } else { 134 sb.append(node.getText()); 135 } 136 } 137 138 public String getName() { 139 return name; 140 } 141 142 public boolean isList() { 143 return isList; 144 } 145 146 public boolean isString() { 147 return isString; 148 } 149 150 public String getPath() { 151 if (path!=null) { 152 return path; 153 } 154 155 // TODO - take match paths from type 156 RuleDefinition rule=owner.getModel().rulesMap.get(type); 157 if (rule!=null) { 158 Collection<Object> matchPaths=rule.getMatchPaths(); 159 if (!matchPaths.isEmpty()) { 160 StringBuffer rsb=new StringBuffer(); 161 Iterator<Object> it=matchPaths.iterator(); 162 while (it.hasNext()) { 163 MatchPath path=(MatchPath) it.next(); 164 if (rsb.length()!=0) { 165 rsb.append("|"); 166 } 167 if (path.isNegation()) { 168 rsb.append("!"); 169 } 170 rsb.append(path.getTokenType()); 171 } 172 return rsb.toString(); 173 } 174 } 175 176 if (type.indexOf('.')==-1) { 177 return "#"+packageName+"."+type; 178 } 179 180 return "#"+type; 181 } 182 183 public String getType() { 184 return type; 185 } 186 }