001: // AttributeRegistry.java
002: // $Id: AttributeRegistry.java,v 1.6 2000/08/16 21:37:50 ylafon Exp $
003: // (c) COPYRIGHT MIT and INRIA, 1996.
004: // Please first read the full copyright statement in file COPYRIGHT.html
005:
006: package org.w3c.tools.resources;
007:
008: import java.util.Hashtable;
009: import java.util.Vector;
010:
011: class ClassAttributes {
012: Attribute fixed[] = null;
013: Vector attrs = null;
014: int nextid = 0;
015:
016: /**
017: * Fix the description of the attributes for this record.
018: */
019:
020: void fix() {
021: if (fixed == null) {
022: fixed = new Attribute[attrs.size()];
023: attrs.copyInto(fixed);
024: attrs = null;
025: }
026: }
027:
028: /**
029: * Add a new attribute description into this record.
030: * @param attr The new attribute description.
031: * @return The attribute index.
032: */
033:
034: int add(Attribute attr) {
035: if (attrs == null)
036: throw new RuntimeException("add in a fixed record.");
037: for (int i = 0; i < attrs.size(); i++) {
038: String name = ((Attribute) attrs.elementAt(i)).getName();
039: if (attr.getName().equals(name))
040: throw new DuplicateNameException(name);
041: }
042: attrs.addElement(attr);
043: return nextid++;
044: }
045:
046: ClassAttributes(int idx) {
047: this .fixed = null;
048: this .attrs = new Vector();
049: this .nextid = idx;
050: }
051:
052: ClassAttributes(ClassAttributes sup) {
053: this .fixed = null;
054: this .attrs = new Vector(sup.fixed.length);
055: this .nextid = sup.nextid;
056: for (int i = 0; i < sup.fixed.length; i++)
057: attrs.addElement(sup.fixed[i]);
058: }
059: }
060:
061: public class AttributeRegistry {
062: private static Hashtable registery = new Hashtable();
063: private static Class top = null;
064:
065: static {
066: try {
067: top = Class
068: .forName("org.w3c.tools.resources.AttributeHolder");
069: } catch (Exception ex) {
070: ex.printStackTrace();
071: System.exit(1);
072: }
073: }
074:
075: /**
076: * Register a new attribute for a given class.
077: * This method create the approrpriate attribute description record if
078: * required, and return the index of this attribute in the corresponding
079: * holder instances.
080: * @param cls The class that defines this attribute.
081: * @param attr The attribute to declare.
082: * @return The attribute index.
083: */
084:
085: public static synchronized int registerAttribute(Class cls,
086: Attribute attr) {
087: // Do we have a description record for this class ?
088: ClassAttributes record = (ClassAttributes) registery.get(cls);
089: if (record == null) {
090: // Create and register the record:
091: if (cls == top) {
092: record = new ClassAttributes(0);
093: } else {
094: // Get our super class record:
095: for (Class clsptr = cls.getSuperclass(); (record == null); clsptr = clsptr
096: .getSuperclass()) {
097: record = (ClassAttributes) registery.get(clsptr);
098: if (clsptr == top) {
099: if (record == null)
100: record = new ClassAttributes(0);
101: break;
102: }
103: }
104: if (record == null)
105: throw new RuntimeException("inconsistent state.");
106: record.fix();
107: record = new ClassAttributes(record);
108: }
109: registery.put(cls, record);
110: }
111: try {
112: return record.add(attr);
113: } catch (DuplicateNameException ex) {
114: System.err.println("Invalid attribute name \""
115: + ex.getName() + "\" " + "in class "
116: + cls.getName() + ".");
117: System.err
118: .println("There is already an attribute defined with "
119: + "this name.");
120: System.err.println("WARNING: Attribute not registered!!");
121: return -1;
122: }
123: }
124:
125: /**
126: * Get this class declared attributes.
127: * @param cls The class we are querying.
128: * @return An array of Attribute instances, describing each of the
129: * attributes of all instances of the class, or <strong>null</strong>
130: * if the class hasn't defined any attributes.
131: */
132:
133: public static synchronized Attribute[] getClassAttributes(Class cls) {
134: Object result = registery.get(cls);
135: while ((cls != top) && (result == null)) {
136: cls = cls.getSuperclass();
137: result = registery.get(cls);
138: }
139: // Fix the resulting record before returning it:
140: if (result == null)
141: return null;
142: ClassAttributes record = (ClassAttributes) result;
143: record.fix();
144: return record.fixed;
145: }
146:
147: /**
148: * Get the name of the class that has declared this attribute.
149: * @param cls The class that makes the starting point of lookup.
150: * @param attr The attribute we are looking for.
151: * @return The name of the class that defined that attribute, or <strong>
152: * null</strong>.
153: */
154:
155: public static Class getAttributeClass(Class cls, String attrname) {
156: Class lookup = cls;
157: // We lookup until we find the class that doesn't have this attribute:
158: while (true) {
159: boolean found = false;
160: Attribute a[] = getClassAttributes(cls);
161: // Lookup the attribute in that set:
162: if (a != null) {
163: for (int i = 0; i < a.length; i++) {
164: if ((found = a[i].getName().equals(attrname)))
165: break;
166: }
167: }
168: if (found) {
169: lookup = cls;
170: cls = cls.getSuperclass();
171: } else {
172: return (lookup == cls) ? null : lookup;
173: }
174: }
175:
176: }
177:
178: }
|