Program: 51866
Project: 51866
Buggy source:
/** 
 * Adds another structMap element to contain the "parent link" that is an essential part of every AIP.  This is a structmap of one div, which contains an mptr indicating the Handle of the parent of this object in the archive.  The div has a unique TYPE attribute value, "AIP Parent Link", and the mptr has a LOCTYPE of "HANDLE" and an xlink:href containing the raw Handle value. <p> Note that the parent Handle has to be stored here because the parent is needed to create a DSpace Object when restoring the AIP; it cannot be determined later once the ingester parses it out of the metadata when the crosswalks are run.  So, since the crosswalks require an object to operate on, and creating the object requires a parent, we cannot depend on metadata processed by crosswalks (e.g.  AIP techMd) for the parent, it has to be at a higher level in the AIP manifest.  The structMap is an obvious and standards-compliant location for it.
 * @param context DSpace context
 * @param dso Current DSpace object
 * @param params Packager Parameters
 * @param mets METS manifest
 * @throws SQLException if database error
 * @throws IOException if IO error
 * @throws AuthorizeException if authorization error
 * @throws MetsException METS Java toolkit exception class.
 */
@Override public void addStructMap(Context context,DSpaceObject dso,PackageParameters params,Mets mets) throws SQLException, IOException, AuthorizeException, MetsException {
  String parentHandle=null;
switch (dso.getType()) {
case Constants.ITEM:
    parentHandle=((Item)dso).getOwningCollection().getHandle();
  break;
case Constants.COLLECTION:
parentHandle=(((Collection)dso).getCommunities()).get(0).getHandle();
break;
case Constants.COMMUNITY:
List<Community> parents=((Community)dso).getParentCommunities();
if (CollectionUtils.isEmpty(parents)) {
parentHandle=siteService.findSite(context).getHandle();
}
 else {
parentHandle=parents.get(0).getHandle();
}
case Constants.SITE:
break;
}
if (parentHandle != null) {
StructMap structMap=new StructMap();
structMap.setID(gensym("String_Node_Str"));
structMap.setTYPE("String_Node_Str");
structMap.setLABEL("String_Node_Str");
Div div0=new Div();
div0.setID(gensym("String_Node_Str"));
div0.setTYPE(PARENT_DIV_TYPE);
div0.setLABEL("String_Node_Str");
Mptr mptr=new Mptr();
mptr.setID(gensym("String_Node_Str"));
mptr.setLOCTYPE(Loctype.HANDLE);
mptr.setXlinkHref(parentHandle);
div0.getContent().add(mptr);
structMap.getContent().add(div0);
mets.getContent().add(structMap);
}
}

Fixed version (ground truth):
/** 
 * Adds another structMap element to contain the "parent link" that is an essential part of every AIP.  This is a structmap of one div, which contains an mptr indicating the Handle of the parent of this object in the archive.  The div has a unique TYPE attribute value, "AIP Parent Link", and the mptr has a LOCTYPE of "HANDLE" and an xlink:href containing the raw Handle value. <p> Note that the parent Handle has to be stored here because the parent is needed to create a DSpace Object when restoring the AIP; it cannot be determined later once the ingester parses it out of the metadata when the crosswalks are run.  So, since the crosswalks require an object to operate on, and creating the object requires a parent, we cannot depend on metadata processed by crosswalks (e.g.  AIP techMd) for the parent, it has to be at a higher level in the AIP manifest.  The structMap is an obvious and standards-compliant location for it.
 * @param context DSpace context
 * @param dso Current DSpace object
 * @param params Packager Parameters
 * @param mets METS manifest
 * @throws SQLException if database error
 * @throws IOException if IO error
 * @throws AuthorizeException if authorization error
 * @throws MetsException METS Java toolkit exception class.
 */
@Override public void addStructMap(Context context,DSpaceObject dso,PackageParameters params,Mets mets) throws SQLException, IOException, AuthorizeException, MetsException {
  String parentHandle=null;
switch (dso.getType()) {
case Constants.ITEM:
    parentHandle=((Item)dso).getOwningCollection().getHandle();
  break;
case Constants.COLLECTION:
parentHandle=(((Collection)dso).getCommunities()).get(0).getHandle();
break;
case Constants.COMMUNITY:
List<Community> parents=((Community)dso).getParentCommunities();
if (CollectionUtils.isEmpty(parents)) {
parentHandle=siteService.findSite(context).getHandle();
}
 else {
parentHandle=parents.get(0).getHandle();
}
break;
case Constants.SITE:
break;
}
if (parentHandle != null) {
StructMap structMap=new StructMap();
structMap.setID(gensym("String_Node_Str"));
structMap.setTYPE("String_Node_Str");
structMap.setLABEL("String_Node_Str");
Div div0=new Div();
div0.setID(gensym("String_Node_Str"));
div0.setTYPE(PARENT_DIV_TYPE);
div0.setLABEL("String_Node_Str");
Mptr mptr=new Mptr();
mptr.setID(gensym("String_Node_Str"));
mptr.setLOCTYPE(Loctype.HANDLE);
mptr.setXlinkHref(parentHandle);
div0.getContent().add(mptr);
structMap.getContent().add(div0);
mets.getContent().add(structMap);
}
}