* @param cd The class definition of the object.
* @param allAttr An array that will be populated with all attribute definitions of the class.
* @param sb The buffer where the import statements are accumulated.
*/
public void getAttributesAndImports(ClassDefinition cd, ArrayList<AttributeDefinition> allAttr, StringBuffer sb){
IntegerVar longestImport = new IntegerVar();
TreeMap<StringName,TypeDefinition> types = new TreeMap<StringName,TypeDefinition>();
TreeMap<StringName,TypeDefinition> iterables = new TreeMap<StringName,TypeDefinition>();
TreeSet<String> genericImports = new TreeSet<String>();
TreeMap<String,TypeAndAttr> typeAndAttr = new TreeMap<String,TypeAndAttr>();
boolean needDmwOmni = false;
// Key: type name
// Value: comment
TreeMap<String,String> uniqueImports = new TreeMap<String, String>();
anyAttributes = false;
cd.adjustJavaClass(genContext,genSuffix);
Iterator<AttributeDefinition> may = cd.getMay();
if (may != null){
while(may.hasNext()){
// NOTE: COMPLICATED! We always add the type of the attribute to our global types
// map EXCEPT IF the type is a non-referential, MULTI/SET attribute. Gaa!
//
// This is because WE DON'T want the primitive type any more, just the TYPEIterableDMW.
// If the value is a single valued type, we'll want the primitive type.
boolean shouldAddType = true;
anyAttributes = true;
AttributeDefinition ad = may.next();
TypeDefinition td = ad.getType();
if (ad.getGenericArgs() != null){
if (ad.getGenericArgs().equals("<DmcObjectName>"))
needDmwOmni = true;
}
switch(ad.getValueType()){
case SINGLE:
anySVAttributes = true;
break;
case HASHMAPPED:
case TREEMAPPED:
anyMVAttributes = true;
if (ad.getType().getIsRefType())
anyMVRefs = true;
iterables.put(td.getName(),td);
break;
case MULTI:
case HASHSET:
case TREESET:
anyMVAttributes = true;
if (ad.getType().getIsRefType())
anyMVRefs = true;
iterables.put(td.getName(),td);
break;
}
if (shouldAddType){
types.put(td.getName(), td);
TypeAndAttr ta = new TypeAndAttr(td,ad.getValueType(),ad.getIndexSize());
typeAndAttr.put(ta.name, ta);
}
appendAttributeInfo(attributeInfo, ad.getName().getNameString(), ad.getDmdID(), ad.getType().getName().getNameString(), ad.getValueType(), ad.getDataType());
if (ad.getGenericArgsImport() != null)
genericImports.add(ad.getGenericArgsImport());
if (ad.getValueType() != ValueTypeEnum.SINGLE){
addImport(uniqueImports, longestImport, ad.getDefinedIn().getDMSASGImport(), "Attribute from " + ad.getDefinedIn().getName() + " schema");
}
allAttr.add(ad);
}
}
Iterator<AttributeDefinition> must = cd.getMust();
if (must != null){
while(must.hasNext()){
// NOTE: COMPLICATED! We always add the type of the attribute to our global types
// map EXCEPT IF the type is a non-referential, MULTI/SET attribute. Gaa!
//
// This is because WE DON'T want the primitive type any more, just the TYPEIterableDMW.
// If the value is a single valued type, we'll want the primitive type.
boolean shouldAddType = true;
anyAttributes = true;
AttributeDefinition ad = must.next();
TypeDefinition td = ad.getType();
if (ad.getGenericArgs() != null){
if (ad.getGenericArgs().equals("<DmcObjectName>"))
needDmwOmni = true;
}
switch(ad.getValueType()){
case SINGLE:
anySVAttributes = true;
break;
case HASHMAPPED:
case TREEMAPPED:
anyMVAttributes = true;
if (ad.getType().getIsRefType())
anyMVRefs = true;
iterables.put(td.getName(),td);
break;
case MULTI:
case HASHSET:
case TREESET:
anyMVAttributes = true;
if (ad.getType().getIsRefType())
anyMVRefs = true;
iterables.put(td.getName(),td);
break;
}
if (shouldAddType){
types.put(td.getName(), td);
TypeAndAttr ta = new TypeAndAttr(td,ad.getValueType(),ad.getIndexSize());
typeAndAttr.put(ta.name, ta);
}
appendAttributeInfo(attributeInfo, ad.getName().getNameString(), ad.getDmdID(), ad.getType().getName().getNameString(), ad.getValueType(), ad.getDataType());
if (ad.getGenericArgsImport() != null)
genericImports.add(ad.getGenericArgsImport());
if (ad.getValueType() != ValueTypeEnum.SINGLE){
addImport(uniqueImports, longestImport, ad.getDefinedIn().getDMSASGImport(), "Attribute from " + ad.getDefinedIn().getName() + " schema");
}
allAttr.add(ad);
}
}
if (cd.getIsNamedBy() != null){
AttributeDefinition isNamedBy = cd.getIsNamedBy();
String nameAttributeType = isNamedBy.getType().getPrimitiveType();
addImport(uniqueImports, longestImport, nameAttributeType, "Is named by");
}
if (useWrappedObjectRefs)
addImport(uniqueImports, longestImport, "org.dmd.dms.*", "Always 2");
if ( (cd.getClassType() != ClassTypeEnum.ABSTRACT) && (cd.getClassType() != ClassTypeEnum.AUXILIARY)){
addImport(uniqueImports, longestImport, "org.dmd.dms.generated.types.DmcTypeModifierMV", "Required for MODREC constructor");
addImport(uniqueImports, longestImport, "org.dmd.dms.generated.dmo.MetaDMSAG", "Required for MODREC constructor");
}
if (cd.getDmwWrapperType(genContext) == WrapperTypeEnum.EXTENDED){
addImport(uniqueImports, longestImport, cd.getDmeImport(), "Required for getModificationRecorder()");
}
if (needDmwOmni)
addImport(uniqueImports, longestImport, "org.dmd.dmw.DmwOmni", "Have DmcObjectName attributes");
if (anyAttributes)
addImport(uniqueImports, longestImport, "org.dmd.dmc.*", "If any attributes");
for(String s: genericImports){
addImport(uniqueImports, longestImport, s, "Generic args import");
}
for(TypeAndAttr ta : typeAndAttr.values()){
TypeDefinition td = ta.td;
if (td.getIsRefType()){
if (useWrappedObjectRefs){
// We have to make some adjustments to handle the fact that we
// may not be generating this code in the same location as the DMOs
td.adjustJavaClass();
addImport(uniqueImports, longestImport, td.getAuxHolderImport(), "Is reference type aux");
// If this is multi-valued, we don't need the REF because we're returning the Iterable
if (ta.valueType == ValueTypeEnum.SINGLE){
if (td.getOriginalClass().getIsNamedBy() == null)
addImport(uniqueImports, longestImport, td.getOriginalClass().getDmoImport(), "Reference to unnamed object");
else
addImport(uniqueImports, longestImport, td.getOriginalClass().getDmtREFImport(), "Is reference type REF");
}
if (cd.getClassType() == ClassTypeEnum.AUXILIARY){
addImport(uniqueImports, longestImport, ta.getImport(), "Reference in an auxiliary class");
}
if (td.getOriginalClass().getIsNamedBy() != null){
if ( (ta.valueType == ValueTypeEnum.TREEMAPPED) || (ta.valueType == ValueTypeEnum.HASHMAPPED) || (ta.indexed))
addImport(uniqueImports, longestImport, td.getOriginalClass().getDmtREFImport(), "To support getMVCopy() for REFs");
}
}
else{
// If this is multi-valued, we don't need the REF because we're returning the Iterable
if (ta.valueType == ValueTypeEnum.SINGLE){
if (td.getOriginalClass().getIsNamedBy() == null)
addImport(uniqueImports, longestImport, td.getOriginalClass().getDmoImport(), "Reference to unnamed object");
else{
if (!td.getIsExtendedRefType())
addImport(uniqueImports, longestImport, td.getOriginalClass().getDmtREFImport(), "Is reference type REF");
}
}
// if (td.getOriginalClass().getIsNamedBy() != null)
addImport(uniqueImports, longestImport, td.getPrimitiveType(), "DMO reference");
if (td.getHelperClassName() != null){
addImport(uniqueImports, longestImport, td.getHelperClassName(), "Helper class");
}
}
}
else if (td.getPrimitiveType() != null){
addImport(uniqueImports, longestImport, td.getPrimitiveType(), "Primitive type");
}
else if (cd.getClassType() == ClassTypeEnum.AUXILIARY){
addImport(uniqueImports, longestImport, ta.getImport(), "Type in an auxiliary class");
}
if (td.getAltType() != null){
if (td.getAltTypeImport() != null)
addImport(uniqueImports, longestImport, td.getAltTypeImport(), "Alternative type for " + td.getName() + " values");
}
if (td.getKeyImport() != null)
addImport(uniqueImports, longestImport, td.getKeyImport(), "Key class");
if (ta.valueType != ValueTypeEnum.SINGLE)
addImport(uniqueImports, longestImport, "java.util.Iterator", "To support getMVCopy()");
switch(ta.valueType){
case SINGLE:
break;
case MULTI:
addImport(uniqueImports, longestImport, "java.util.ArrayList", "To support getMVCopy()");
break;
case HASHMAPPED:
if (useWrappedObjectRefs)
addImport(uniqueImports, longestImport, "java.util.HashMap", "To support getMVCopy()");
break;
case TREEMAPPED:
if (useWrappedObjectRefs)
addImport(uniqueImports, longestImport, "java.util.TreeMap", "To support getMVCopy()");
break;
case HASHSET:
addImport(uniqueImports, longestImport, "java.util.HashSet", "To support getMVCopy()");
break;
case TREESET:
addImport(uniqueImports, longestImport, "java.util.TreeSet", "To support getMVCopy()");
break;
}
}
if (useWrappedObjectRefs){
Iterator<TypeDefinition> t = iterables.values().iterator();
while(t.hasNext()){
TypeDefinition td = t.next();
addImport(uniqueImports, longestImport, td.getDmwIteratorImport(), "For multi-valued " + td.getName().getNameString());
if (td.getPrimitiveType() != null)
addImport(uniqueImports, longestImport, td.getPrimitiveType(), "For multi-valued contains" + td.getName().getNameString());
}
}
if (cd.getClassType() == ClassTypeEnum.ABSTRACT){
addImport(uniqueImports, longestImport, cd.getDmoImport(), "Abstract class");
}
if (cd.getDerivedFrom() == null){
if (cd.getIsNamedBy() == null){
addImport(uniqueImports, longestImport, baseWrapperImport, "Unnamed object wrapper");
}
else{
if (cd.getIsNamedBy().getType().getIsHierarchicName()){
addImport(uniqueImports, longestImport, hierarchicWrapperImport, "Hierarchic object wrapper");
}
else{
addImport(uniqueImports, longestImport, namedWrapperImport, "Named object wrapper");
}
}
}
else{
cd.getDerivedFrom().adjustJavaClass(genContext,genSuffix);
addImport(uniqueImports, longestImport, cd.getDerivedFrom().getJavaClass(), "Derived class");
}
if ((cd.getClassType() != ClassTypeEnum.AUXILIARY) && (cd.getClassType() != ClassTypeEnum.ABSTRACT)){
addImport(uniqueImports, longestImport, cd.getDmoImport(), "Class not auxiliary or abstract");
}
sb.append(formatImports(uniqueImports, longestImport.intValue()));
}