if (isAugmentable()) {
// loop over class fields to declare them to the model
for (final Enumeration e = classFile.fields().elements();
e.hasMoreElements();) {
final ClassField field = (ClassField)e.nextElement();
final String name = field.name().asString();
final String sig = field.signature().asString();
// skip jdo fields
if (jdoFieldNames.contains(name)) {
continue;
}
// skip static fields
if (field.isStatic()) {
continue;
}
// skip known non-managed fields
if (meta.isKnownNonManagedField(className, name, sig)) {
continue;
}
// remember field requiring accessor/mutator
Object obj = annotatedFieldMap.put(name, field);
affirm(obj == null,
("Error in classfile: repeated declaration of field: "
+ userClassName + "." + name));
// skip final, transient fields
if (field.isFinal()
|| field.isTransient()) {
continue;
}
if (false) {
System.out.println("Analyzer.scanFields(): declaring "
+ className + "." + name + " : " + sig);
}
meta.declareField(className, name, sig);
}
}
// nr of fields needing accessor/mutator methods
annotatedFieldCount = annotatedFieldMap.size();
// get managed field names from meta data
final String[] managedFieldNames = meta.getManagedFields(className);
affirm(managedFieldNames != null);
managedFieldCount = managedFieldNames.length;
final Set managedFieldNamesSet
= new HashSet(Arrays.asList(managedFieldNames));
affirm(managedFieldNamesSet.size() == managedFieldCount,
"JDO metadata: returned duplicate managed fields.");
affirm(managedFieldCount <= annotatedFieldCount,
"JDO metadata: managed fields exceed annotated fields.");
// data structures for key fields
final String[] keyFieldNames = meta.getKeyFields(className);
affirm(keyFieldNames != null);
keyFieldCount = keyFieldNames.length;
affirm(keyFieldCount == 0 || keyClassName != null,
"JDO metadata: returned key fields but no key class.");
final Set keyFieldNamesSet
= new HashSet(Arrays.asList(keyFieldNames));
affirm(keyFieldNamesSet.size() == keyFieldCount,
"JDO metadata: returned duplicate key fields.");
affirm(keyFieldCount <= managedFieldCount,
"JDO metadata: key fields exceed managed fields.");
// loop over class fields to compute 'jdo*' and key/managed fields
for (final Enumeration e = classFile.fields().elements();
e.hasMoreElements();) {
final ClassField field = (ClassField)e.nextElement();
final String name = field.name().asString();
final String sig = field.signature().asString();
final String userFieldName = userClassName + "." + name;
if (false) {
System.out.println("Analyzer.scanFields(): scanning "
+ className + "." + name + " : " + sig);
}
// map 'jdo*' field names to class fields
if (name.startsWith("jdo")) {
final Object f = jdoLikeFields.put(name, field);
affirm(f == null);
}
// skip non-managed fields
if (!managedFieldNamesSet.contains(name)) {
affirm(!meta.isManagedField(className, name));
// check for non-managed key field
affirm(!keyFieldNamesSet.contains(name),
("JDO metadata: reported the field " + userFieldName
+ " to be non-managed but key."));
continue;
}
affirm(meta.isManagedField(className, name));
// check for managed static field
affirm(!field.isStatic(),
("JDO metadata: reported the field " + userFieldName
+ " to be managed though it's static."));
// check for managed final field
affirm(!field.isFinal(),
("JDO metadata: reported the field " + userFieldName
+ " to be managed though it's final."));
// allow for managed transient fields
//^olsen: adopt
/*
r[i++] = hasField(
out,
Modifier.PRIVATE | Modifier.FINAL | Modifier.STATIC,
long.class,
"serialVersionUID");
*/
}
// get the managed field flags ordered by relative index
final int[] managedFieldFlags
= meta.getFieldFlags(className, managedFieldNames);
// compute the managed field types ordered by relative index
// and key field indexes
int j = 0;
keyFieldIndexes = new int[keyFieldCount];
final String[] managedFieldSigs = new String[managedFieldCount];
final int[] managedFieldMods = new int[managedFieldCount];
for (int i = 0; i < managedFieldCount; i++) {
final String name = managedFieldNames[i];
affirm(name != null);
// assert consistency between Java and JDO metadata
final ClassField field = (ClassField)annotatedFieldMap.get(name);
affirm(field != null,
("The managed field " + userClassName + "." + name +
" is not declared by the class."));
affirm(!field.isStatic(),
("The managed field " + userClassName + "." + name +
" is static."));
affirm(!field.isFinal(),
("The managed field " + userClassName + "." + name +
" is final."));
// mark managed field as taken care of
annotatedFieldMap.remove(name);
// assign key field index
if (keyFieldNamesSet.contains(name)) {
affirm(meta.isKeyField(className, name));
keyFieldIndexes[j++] = i;
}
// add field type and Java access modifers
managedFieldSigs[i] = field.signature().asString();
managedFieldMods[i] = field.access();
// set the serializable bit if field is not (Java) transient
// This code might be removed as soon as the metadata is able
// to retrieve the info as part of meta.getFieldFlags.
if (!field.isTransient()) {
managedFieldFlags[i] |= EnhancerMetaData.SERIALIZABLE;
}
if (false) {
System.out.println("managed field: "
+ className + "." + name + " : {");
System.out.println(" sigs = " + managedFieldSigs[i]);
System.out.println(" mods = "
+ Integer.toHexString(managedFieldMods[i]));
System.out.println(" flags = "
+ Integer.toHexString(managedFieldFlags[i]));
}
}
// post conditions of managed/key field processing
affirm(keyFieldIndexes.length == keyFieldCount);
affirm(keyFieldCount <= managedFieldCount);
affirm(managedFieldNames.length == managedFieldCount);
affirm(managedFieldSigs.length == managedFieldCount);
affirm(managedFieldMods.length == managedFieldCount);
affirm(managedFieldFlags.length == managedFieldCount);
affirm(managedFieldCount <= annotatedFieldCount);
// assign the annotated field arrays
if (managedFieldCount == annotatedFieldCount) {
// return if the annotated fields are equal to the managed ones
annotatedFieldNames = managedFieldNames;
annotatedFieldSigs = managedFieldSigs;
annotatedFieldMods = managedFieldMods;
annotatedFieldFlags = managedFieldFlags;
} else {
// fill the annotated field arrays with the managed ones
annotatedFieldNames = new String[annotatedFieldCount];
annotatedFieldSigs = new String[annotatedFieldCount];
annotatedFieldMods = new int[annotatedFieldCount];
annotatedFieldFlags = new int[annotatedFieldCount];
int i = managedFieldCount;
System.arraycopy(managedFieldNames, 0, annotatedFieldNames, 0, i);
System.arraycopy(managedFieldSigs, 0, annotatedFieldSigs, 0, i);
System.arraycopy(managedFieldMods, 0, annotatedFieldMods, 0, i);
System.arraycopy(managedFieldFlags, 0, annotatedFieldFlags, 0, i);
// append the annotated, non-managed fields
for (Iterator k = annotatedFieldMap.entrySet().iterator();
k.hasNext();) {
final Map.Entry entry = (Map.Entry)k.next();
final String name = (String)entry.getKey();
final ClassField field = (ClassField)entry.getValue();
affirm(name.equals(field.name().asString()));
affirm(!field.isStatic(),
("The managed field " + userClassName + "." + name +
" is static."));
// add field type and Java access modifers
annotatedFieldNames[i] = name;
annotatedFieldSigs[i] = field.signature().asString();
annotatedFieldMods[i] = field.access();
annotatedFieldFlags[i] = 0x0; // direct read/write access
i++;
}
affirm(i == annotatedFieldCount);
}