1 9 10 23 24 25 28 29 package JSX; 30 31 import java.io.*; 32 import java.util.*; 33 import java.lang.reflect.*; 34 35 36 public class DTDGenerator { 38 static final boolean DEBUG = false; 40 41 PrintWriter out; 42 public DTDGenerator(Writer writer) { 43 this.out = new PrintWriter(writer); 44 } 45 46 47 53 HashSet classList = new HashSet(); 54 void populate(Object obj) { classList.add(obj.getClass()); 56 } 57 58 59 75 76 HashSet entitiesDone = new HashSet(); 77 void generate() { 78 if (DEBUG) System.err.println(classList); 79 classList.add(NULL); classList.add(ALIASREF); 81 Object [] c = (Object []) classList.toArray(new Object [0]); 82 classList.clear(); entitiesDone.clear(); 84 writeDTD(c); 85 } 87 88 89 90 public void writeDTD(Object [] classList) { 91 for (int i=0; i<classList.length; i++) { 92 SepFields r; 94 Object obj = classList[i]; 95 if (obj instanceof Class ) { 96 Class clazz = (Class ) obj; 97 r = custom(clazz); 98 if (r==null) r = sepFields(clazz); 99 r.primList.add(XMLSerialize.ALIAS_ID_TOKEN); 101 } else if (obj instanceof SyntheticClass) { 102 r = ((SyntheticClass) obj).sepFields; } else throw new InternalError ("expected Class or SyntheticClass"); 104 105 r.primList.add(XMLSerialize.NAME_TOKEN); 107 ArrayList allRefList = getSubclasses(r.refList, classList); 108 109 String className; 111 if (obj instanceof Class ) { Class clazz = (Class ) obj; 113 className = getClassName(clazz); 114 } else if (obj instanceof SyntheticClass) { 115 className = ((SyntheticClass) obj).className; 116 } else throw new InternalError ("expected Class or SyntheticClass"); 117 writeElement(className, allRefList); writeAttList(className, r.primList); 119 } 120 out.flush(); 121 } 122 123 124 125 static final SyntheticClass NULL; 126 static final SyntheticClass ALIASREF; 127 static { 128 NULL = new SyntheticClass(XMLSerialize.NULL_TOKEN); 130 ALIASREF = new SyntheticClass(XMLSerialize.ALIAS_TAG_TOKEN); 132 ALIASREF.sepFields.primList.add(XMLSerialize.ALIAS_ATTR_TOKEN); 133 } 134 135 String getClassName(Class clazz) { 136 String className; 137 if (clazz.isArray()) { 138 if (clazz.getComponentType()==byte.class) 139 className = XMLSerialize.BINARY_DATA_TOKEN; 140 else 141 className = XMLSerialize.getArrayType(clazz); 142 } 143 else className = clazz.getName(); 144 return ParseUtilities.escapeDollar(className); } 146 147 SepFields sepFields(Class clazz) { 148 Field[] f = clazz.getDeclaredFields(); ArrayList primCache = new ArrayList(); 151 ArrayList refCache = new ArrayList(); 152 for (int i=0; i<f.length; i++) { 153 Field field = f[i]; 154 Class type = field.getType(); 155 if (type.isPrimitive() || type==String .class) primCache.add(field); 156 else refCache.add(field); 157 } 158 return new SepFields(refCache, primCache); 159 } 160 161 SepFields custom(Class clazz) { 162 SepFields r = null; 163 if (clazz.isArray()) { 164 r = new SepFields(); 165 r.primList.add(XMLSerialize.LENGTH_TOKEN); Class component = clazz.getComponentType(); if (!component.isPrimitive()) 168 r.refList.add(clazz.getComponentType()); else if (component==byte.class) { 170 r.primList.add(XMLSerialize.VALUE_TOKEN); } else { } 177 } else if (clazz==Boolean .class || clazz==Byte .class || 179 clazz==Short .class || 180 clazz==Integer .class || 181 clazz==Long .class || 182 clazz==Float .class || 183 clazz==Double .class || 184 clazz==String .class || clazz==Character .class) { r = new SepFields(); 187 r.primList.add(XMLSerialize.VALUE_TOKEN); } else if (clazz==Vector.class) { 190 r = new SepFields(); 191 r.refList.add(Object .class); } else if (clazz==Hashtable.class) { r = new SepFields(); 194 r.refList.add(Object .class); } else if (clazz==Class .class) { 196 r = new SepFields(); 197 r.primList.add(XMLSerialize.CLASSNAME_TOKEN); } 199 return r; 200 } 201 202 203 ArrayList getSubclasses(ArrayList refList, Object [] classList) { 208 if (DEBUG) System.err.println("Starting Subclasses"); 209 ArrayList result = new ArrayList(); 210 for (Iterator i=refList.listIterator(); i.hasNext(); ) { 211 Class type; 212 Object ref = i.next(); 213 if (ref instanceof Field) type = ((Field)ref).getType(); 215 else if (ref instanceof Class ) 216 type = (Class ) ref; 217 else throw new InternalError ("Expected a Field or Class; got a "+ref.getClass()); 218 if (DEBUG) System.err.println("\tField of type: "+type); 219 220 result.add(type); 222 if (!entitiesDone.contains(type)) { 224 entitiesDone.add(type); 225 out.print("<!ENTITY % "+getClassName(type)+" \"("); 226 boolean firstOne = true; 227 for (int j=0; j<classList.length; j++) { 228 Object obj = classList[j]; 229 if (obj instanceof Class ) { if (type.isAssignableFrom((Class )obj)) { 231 if (firstOne) firstOne = false; 234 else out.print("|"); 235 out.print(getClassName((Class )obj)); 236 } 237 } else if (obj instanceof SyntheticClass) { 238 if (firstOne) firstOne = false; 240 else out.print("|"); 241 out.print(((SyntheticClass)obj).className); 242 } else throw new InternalError ("expected Class or SyntheticClass"); 243 } 244 out.println(")\">"); 245 if (DEBUG) System.err.println("\t\tresult so far: "+result); 246 } 247 } 248 249 250 return result; 251 } 252 253 254 255 void writeElement(String elementName, ArrayList refList) { 260 out.print("<!ELEMENT "+elementName+" "); 261 boolean firstOne = true; 268 for (Iterator i=refList.listIterator(); i.hasNext(); ) { 269 if (firstOne) { 270 firstOne = false; 271 out.print("("); } else { 273 out.print("|"); 274 } 275 Object obj = i.next(); 276 String className; if (obj instanceof Class ) { Class clazz = (Class ) obj; 279 className = getClassName(clazz); 280 } else if (obj instanceof SyntheticClass) { 281 className = ((SyntheticClass) obj).className; 282 } else throw new InternalError ("expected Class or SyntheticClass"); 283 out.print("%"+className+";"); } 285 if (firstOne) out.print("EMPTY"); else out.print(")*"); 288 out.println(">"); } 290 291 void writeAttList(String className, ArrayList attList) { 298 boolean firstPrim = true; 299 if (DEBUG) System.err.println(attList); 300 for (Iterator i=attList.listIterator(); i.hasNext(); ) { 301 if (firstPrim) { 302 out.println("<!ATTLIST " + className); firstPrim = false; } 305 Object f = i.next(); 306 if (f instanceof Field) 307 out.println(" " + ((Field)f).getName() + " CDATA #IMPLIED"); 308 else if (f instanceof String ) 309 out.println(" " + f + " CDATA #IMPLIED"); 310 311 } 312 if (!firstPrim) { out.println(">"); 315 } 316 } 317 318 319 320 321 int a; 322 int b; 323 int c; 324 Object o; 325 public static void main(String [] args) throws Exception { 326 Class [] c = {String .class, DTDGenerator.class, XMLSerialize.class}; 327 DTDGenerator generator=new DTDGenerator(new OutputStreamWriter(System.out)); 328 generator.writeDTD(c); 329 } 330 331 } 332 333 334 class SyntheticClass { 335 String className; 336 SepFields sepFields = new SepFields(); 337 SyntheticClass(String className) { 338 this.className = className; 339 } 340 } 341 342 class SepFields { 344 ArrayList refList; 345 ArrayList primList; 346 SepFields() { 347 this.refList = new ArrayList(); 348 this.primList = new ArrayList(); 349 } 350 SepFields(ArrayList refList, ArrayList primList) { 351 this.refList = refList; 352 this.primList = primList; 353 } 354 } 355 356 363 364 368 369 373 374 377 378 389
| Popular Tags
|