1 12 package org.eclipse.ant.internal.ui.dtd.schema; 13 14 import com.ibm.icu.text.MessageFormat; 15 import java.util.HashSet ; 16 import java.util.LinkedList ; 17 18 import org.eclipse.ant.internal.ui.dtd.IModel; 19 import org.eclipse.ant.internal.ui.dtd.ISchema; 20 import org.xml.sax.SAXException ; 21 import org.xml.sax.ext.DeclHandler ; 22 23 32 public class SchemaFactory implements DeclHandler { 33 private char[] fBuf; 35 private int fLen; 36 private int fPos; 37 private Element fElement; 38 39 private Schema fSchema; 40 private static HashSet fTypes = new HashSet (); 41 private Exception fErrorException; 42 static { 43 fTypes.add("CDATA"); fTypes.add("ID"); fTypes.add("IDREF"); fTypes.add("IDREFS"); fTypes.add("NMTOKEN"); fTypes.add("NMTOKENS"); fTypes.add("ENTITY"); fTypes.add("ENTITIES"); } 52 53 56 public SchemaFactory() { 57 fSchema = new Schema(); 58 } 59 60 65 public ISchema getSchema() { 66 fSchema.setErrorException(fErrorException); 67 return fSchema; 68 } 69 70 73 public void attributeDecl(String eName, String aName, String type, String valueDefault, String value) { 74 Element element = getElement(eName); 75 Attribute attr = (Attribute) element.getAttributes().get(aName); 76 if (attr == null) { 77 attr = new Attribute(aName, element); 78 element.addAttribute(attr); 79 80 String [] enumeration = null; 81 if (fTypes.contains(type)) 82 attr.setType(type); 83 else if (type.startsWith("NOTATION")) enumeration = parseValues(type.substring("NOTATION".length()+1), ','); else { 86 type = stripSurroundingParentheses(type); 87 enumeration = parseValues(type, '|'); 88 } 89 attr.setEnum(enumeration); 90 91 attr.setRequired(valueDefault == null || !valueDefault.equals("#IMPLIED")); attr.setFixed(valueDefault != null && valueDefault.equals("#FIXED")); attr.setDefault(value); 94 } 95 } 96 97 98 103 private String stripSurroundingParentheses(String aString) { 104 if(aString.startsWith("(")) { aString = aString.substring(1); 106 } 107 if(aString.endsWith(")")) { aString = aString.substring(0, aString.length()-1); 109 } 110 return aString; 111 } 112 113 114 119 private Element getElement(String eName) { 120 Element element = (Element) fSchema.getElement(eName); 121 if (element == null) { 122 element = new Element(eName); 123 fSchema.addElement(element); 124 } 125 return element; 126 } 127 128 private String [] parseValues(String type, char separator) { 129 int start = 0, pos, len = type.length(); 130 LinkedList values = new LinkedList (); 131 while (start < len) { 132 pos = type.indexOf(separator, start); 133 if (pos < 0) pos = len; 134 String term = type.substring(start, pos); 135 start = pos + 1; 136 values.add(term); 137 } 138 return (String []) values.toArray(new String [values.size()]); 139 } 140 141 144 public void elementDecl(String name, String model) throws SAXException { 145 Element element = getElement(name); 146 if (!element.isUndefined()) { 147 throw new SAXException (MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Doubly_defined, new String []{name})); 149 } 150 151 fElement = element; 152 if (model.equals("ANY")) { element.setAny(true); 154 } else if (model.equals("EMPTY")) { element.setEmpty(true); 156 } else if (model.equals("(#PCDATA)")) { element.setText(true); 158 } else { 159 element.setContentModel(parseModel(model)); 160 } 161 } 162 163 175 private IModel parseModel(String model) throws SAXException { 176 fBuf = model.toCharArray(); 177 fLen = fBuf.length; 178 if (fBuf[0] != '(') { 179 throw new SAXException ( 180 MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Start_with_left_parenthesis, new String []{fElement.getName()})); 181 } 182 183 boolean ortext = model.startsWith("(#PCDATA|"); if (ortext) { 185 fPos = 8; } else { 187 fPos = 0; 188 } 189 IModel emodel= scanExpr(); 190 return emodel; 191 } 192 193 198 private IModel scanExpr() throws SAXException { 199 fPos++; 201 return scanExpr(scanElement()); 202 } 203 204 211 private IModel scanExpr(IModel term) throws SAXException { 212 checkLen(); 213 if (fBuf[fPos] != ')') { 214 char op = fBuf[fPos]; 215 if (op != '|' && op != ',') { 216 throw new SAXException ( 217 MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Expecting_operator_or_right_parenthesis, 218 new String []{fElement.getName(),String.valueOf(fBuf)})); 219 } 220 Model model = new Model(op == '|' ? IModel.CHOICE : IModel.SEQUENCE); 221 model.addModel(term); 222 term = model; 223 224 while (fBuf[fPos] == op) { 225 fPos++; 226 IModel next = scanElement(); 227 model.addModel(next); 228 } 229 if (fBuf[fPos] != ')') { 230 throw new SAXException ( 231 MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Expecting_operator_or_right_parenthesis, 232 new String []{fElement.getName(), String.valueOf(fBuf)})); 233 } 234 fPos++; 235 } 236 return term; 237 } 238 239 244 private IModel scanElement() throws SAXException { 245 checkLen(); 246 if (fBuf[fPos] == '(') 247 return scanExpr(); 248 StringBuffer sb = new StringBuffer (); 249 while (fBuf[fPos] != '|' && fBuf[fPos] != ',' && fBuf[fPos] != ')' 250 && fBuf[fPos] != '*' && fBuf[fPos] != '+' && fBuf[fPos] != '?' ) { 251 sb.append(fBuf[fPos++]); 252 checkLen(); 253 } 254 String name = sb.toString(); 255 Element element = getElement(name); 256 Model model = new Model(IModel.LEAF); 257 model.setLeaf(element); 258 return model; 259 } 260 261 private void checkLen() throws SAXException { 262 if (fPos == fLen) { 263 throw new SAXException ( 264 MessageFormat.format(AntDTDSchemaMessages.SchemaFactory_Unexpected_end, 265 new String []{fElement.getName(), 266 String.valueOf(fBuf)})); 267 } 268 } 269 270 273 public void externalEntityDecl(String name, String publicId, String systemId) { 274 } 275 276 279 public void internalEntityDecl(String name, String value) { 280 } 281 282 public void setErrorException(Exception e) { 283 fErrorException = e; 284 } 285 } 286 | Popular Tags |