RelationsCommonList parentListOuter = getRelations(thisCSID, null, predicate);
List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
if (parentList != null) {
+ if (parentList.size()==0){
+ return null;
+ }
RelationsCommonList.RelationListItem relationListItem = parentList.get(0);
parentCSID = relationListItem.getObjectCsid();
}
List<RelationsCommonList.RelationListItem> childList = childListOuter.getRelationListItem();
List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
+ if (parentList.size()>1){
+ throw new Exception("Too many parents for object: "+itemCSID+" list: "+dumpList(parentList, "parentList"));
+ }
+
DocumentModel docModel = wrapDoc.getWrappedObject();
//Do magic replacement of ${itemCSID} and fix URI's.
for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
if (inboundItem.getObject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
- //then this is an item that says we have a child.
+ //then this is an item that says we have a child. That child is inboundItem
RelationsCommonList.RelationListItem childItem = findInList(childList, inboundItem);
if (childItem != null){
removeFromList(childList, childItem); //exists, just take it off delete list
} else {
actionList.add(inboundItem); //doesn't exist as a child, but is a child. Add to additions list
}
+ ensureChildHasNoOtherParents(ctx, queryParams, inboundItem.getSubject().getCsid());
+
} else if (inboundItem.getSubject().getCsid().equals(itemCSID) && inboundItem.getPredicate().equals(HAS_BROADER)) {
- //then this is an item that says we have a parent
+ //then this is an item that says we have a parent. inboundItem is that parent.
RelationsCommonList.RelationListItem parentItem = findInList(parentList, inboundItem);
if (parentItem != null){
removeFromList(parentList, parentItem); //exists, just take it off delete list
//not dealing with: hasNarrower or any other predicate.
}
}
- deleteRelations(parentList, ctx); //todo: there are items appearing on both lists....april 20.
- deleteRelations(childList, ctx);
+ String dump = dumpLists(itemCSID, parentList, childList, actionList);
+ //System.out.println("====dump====="+CR+dump);
+ logger.info("~~~~~~~~~~~~~~~~~~~~~~dump~~~~~~~~~~~~~~~~~~~~~~~~"+CR+ dump);
+ deleteRelations(parentList, ctx, "parentList"); //todo: there are items appearing on both lists....april 20.
+ deleteRelations(childList, ctx, "childList");
createRelations(actionList, ctx);
//We return all elements on the inbound list, since we have just worked to make them exist in the system
// and be non-redundant, etc. That list came from relationsCommonListBody, so it is still attached to it, just pass that back.
return relationsCommonListBody;
}
+ private void ensureChildHasNoOtherParents(ServiceContext ctx, MultivaluedMap queryParams, String childCSID){
+ queryParams.putSingle(IRelationsManager.SUBJECT_QP, childCSID);
+ queryParams.putSingle(IRelationsManager.PREDICATE_QP, RelationshipType.HAS_BROADER.value());
+ queryParams.putSingle(IRelationsManager.OBJECT_QP, null); //null means ANY
+ RelationsCommonList parentListOuter = (new RelationResource()).getList(ctx.getUriInfo());
+ List<RelationsCommonList.RelationListItem> parentList = parentListOuter.getRelationListItem();
+ //logger.warn("ensureChildHasNoOtherParents preparing to delete relations on "+childCSID+"\'s parent list: \r\n"+dumpList(parentList, "duplicate parent list"));
+ deleteRelations(parentList, ctx, "parentList-delete");
+ }
+
+ private String dumpLists(String itemCSID,
+ List <RelationsCommonList.RelationListItem> parentList,
+ List<RelationsCommonList.RelationListItem> childList,
+ List<RelationsCommonList.RelationListItem> actionList){
+ StringBuffer sb = new StringBuffer();
+ sb.append("itemCSID: "+itemCSID+CR);
+ sb.append(dumpList(parentList, "parentList"));
+ sb.append(dumpList(childList, "childList"));
+ sb.append(dumpList(actionList, "actionList"));
+ return sb.toString();
+ }
+
+ private final static String CR="\r\n";
+ private final static String T = " ";
+
+ private String dumpList(List <RelationsCommonList.RelationListItem> list, String label){
+ StringBuffer sb = new StringBuffer();
+ String s;
+ if (list.size()>0) sb.append("=========== "+label+" =========="+CR);
+ for (RelationsCommonList.RelationListItem item : list) {
+ s =
+ T + item.getSubject().getCsid() //+T4 + item.getSubject().getUri()
+ + T + item.getPredicate()
+ + T + item.getObject().getCsid() //+T4 + item.getObject().getUri()
+ + CR
+ //+"subject:{"+item.getSubject()+"}\r\n object:{"+item.getObject()+"}"
+ //+ CR + "relation-record: {"+item+"}"
+ ;
+ sb.append(s);
+
+ }
+ return sb.toString();
+ }
+
/** Performs substitution for ${itemCSID} (see CommonAPI.AuthorityItemCSID_REPLACE for constant)
* and sets URI correctly for related items.
* Operates directly on the items in the list. Does not change the list ordering, does not add or remove any items.
Object res = relationResource.create(ctx.getUriInfo(), payloadOut.toXML()); //NOTE ui recycled from above to pass in unknown query params.
}
}
- private void deleteRelations(List<RelationsCommonList.RelationListItem> list,ServiceContext ctx){
+ private void deleteRelations(List<RelationsCommonList.RelationListItem> list,ServiceContext ctx, String listName){
try {
- for (RelationsCommonList.RelationListItem inboundItem : list) {
+ //if (list.size()>0){ logger.info("==== deleteRelations from : "+listName); }
+ for (RelationsCommonList.RelationListItem item : list) {
RelationResource relationResource = new RelationResource();
- //System.out.println("\r\n==== TO DELETE: "+inboundItem.getCsid());
- Object res = relationResource.delete(inboundItem.getCsid());
+ //logger.info("==== TO DELETE: " + item.getCsid() + ": " + item.getSubject().getCsid() + "--" + item.getPredicate() + "-->" + item.getObject().getCsid());
+ Object res = relationResource.delete(item.getCsid());
}
} catch (Throwable t){
String msg = "Unable to deleteRelations: "+ Tools.errorToString(t, true);
}\r
\r
public static String getStackTrace(Throwable e){\r
+ return getStackTrace(e, -1);\r
+ }\r
+\r
+\r
+ /** @param includeLines if zero, returns all lines */\r
+ public static String getStackTrace(Throwable e, int includeLines){\r
if (e==null){\r
return "";\r
}\r
else System.out.println("bos was null, not closing");\r
} catch (Exception e2) {System.out.println("ERROR: couldn't reset() bos in Tools "+e2);}\r
\r
- return result;\r
+ if (includeLines == 0){\r
+ return result; //return all.\r
+ }\r
+ StringBuffer sb = new StringBuffer();\r
+ int i = 0;\r
+ String[] foo = result.split("\n");\r
+ for (String line: foo){\r
+ i++;\r
+ if (i>includeLines){\r
+ sb.append(" ...first "+i+" lines. "+(foo.length-i)+" more.\r\n");\r
+ return sb.toString();\r
+ }\r
+ sb.append(line).append("\r\n");\r
+ }\r
+ return sb.toString();\r
+ }\r
+\r
+ public static String errorToString(Throwable e, boolean stackTraceOnException){\r
+ return errorToString(e, stackTraceOnException, 0);\r
}\r
\r
/** Takes an Exception object and formats a message that provides more debug information\r
* suitable for developers for printing to System.out or for logging. Not suitable for\r
* presentation of error messages to clients.\r
+ * @param includeLines if zero, return all lines of stack trace, otherwise return number of lines from top.\r
*/\r
- public static String errorToString(Throwable e, boolean stackTraceOnException){\r
+ public static String errorToString(Throwable e, boolean stackTraceOnException, int includeLines){\r
if (e==null){\r
return "";\r
}\r
if (causeBuffer.length()>0) s = s + "\r\n -- Causes: "+causeBuffer.toString();\r
\r
\r
- s = s + "\r\n -- Stack Trace: \r\n -- " + getStackTrace(e);\r
+ s = s + "\r\n -- Stack Trace: \r\n -- " + getStackTrace(e, includeLines);\r
return s;\r
}\r
\r
if (logger.isDebugEnabled()) {\r
logger.debug(getClass().getName(), e);\r
}\r
- /* ===== how RoleResource does it: =======\r
- } catch (BadRequestException bre) {\r
- response = Response.status(\r
- Response.Status.BAD_REQUEST).entity(ServiceMessages.POST_FAILED\r
- + bre.getErrorReason()).type("text/plain").build();\r
- throw new WebApplicationException(response);\r
- } catch (DocumentException bre) {\r
- response = Response.status(\r
- Response.Status.BAD_REQUEST).entity(ServiceMessages.POST_FAILED\r
- + bre.getErrorReason()).type("text/plain").build();\r
- throw new WebApplicationException(response);\r
- } catch (UnauthorizedException ue) {\r
- response = Response.status(\r
- Response.Status.UNAUTHORIZED).entity(ServiceMessages.POST_FAILED\r
- + ue.getErrorReason()).type("text/plain").build();\r
- throw new WebApplicationException(response);\r
- */\r
+ String detail = Tools.errorToString(e, true);\r
+ String detailNoTrace = Tools.errorToString(e, true, 3);\r
+ logger.error(getClass().getName()+" detail: "+detailNoTrace, e);\r
\r
if (e instanceof UnauthorizedException) {\r
response = Response.status(Response.Status.UNAUTHORIZED).entity(serviceMsg + e.getMessage()).type("text/plain").build();\r
return (WebApplicationException) e;\r
\r
} else { // e is now instanceof Exception\r
- String detail = Tools.errorToString(e, true);\r
- response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(serviceMsg + " detail: " + detail).type("text/plain").build();\r
+ response = Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(serviceMsg + " detail: " + detailNoTrace).type("text/plain").build();\r
return new WebApplicationException(response);\r
}\r
}\r
propName = ServiceBindingUtils.getPropertyValue(itemSbt, ServiceBindingUtils.OBJ_NAME_PROP);
String itemDocname = ServiceBindingUtils.getMappedFieldInDoc(itemSbt, ServiceBindingUtils.OBJ_NAME_PROP, itemDocModel);
if (propName==null || itemDocname==null){
- System.out.println("=== prop NOT found: "+ServiceBindingUtils.OBJ_NAME_PROP+"::"+propName+"="+itemDocname+" documentType: "+documentType);
+ //System.out.println("=== prop NOT found: "+ServiceBindingUtils.OBJ_NAME_PROP+"::"+propName+"="+itemDocname+" documentType: "+documentType);
} else{
item.setName(itemDocname);
- System.out.println("=== found prop : "+ServiceBindingUtils.OBJ_NAME_PROP+"::"+propName+"="+itemDocname+" documentType: "+documentType);
+ //System.out.println("=== found prop : "+ServiceBindingUtils.OBJ_NAME_PROP+"::"+propName+"="+itemDocname+" documentType: "+documentType);
}
} catch (Throwable t){
System.out.println("====Error finding objectNameProperty: "+itemDocModel+" field "+ServiceBindingUtils.OBJ_NAME_PROP+"="+propName
String itemDocnumber = ServiceBindingUtils.getMappedFieldInDoc(itemSbt, ServiceBindingUtils.OBJ_NUMBER_PROP, itemDocModel);
if (propName==null || itemDocnumber==null){
- System.out.println("=== prop NOT found: "+ServiceBindingUtils.OBJ_NUMBER_PROP+"::"+propName+"="+itemDocnumber
- +" documentType: "+documentType);
+ //System.out.println("=== prop NOT found: "+ServiceBindingUtils.OBJ_NUMBER_PROP+"::"+propName+"="+itemDocnumber
+ // +" documentType: "+documentType);
} else {
item.setNumber(itemDocnumber);
- System.out.println("============ found prop : "+ServiceBindingUtils.OBJ_NUMBER_PROP+"::"+propName+"="+itemDocnumber
- +" documentType: "+documentType);
+ //System.out.println("============ found prop : "+ServiceBindingUtils.OBJ_NUMBER_PROP+"::"+propName+"="+itemDocnumber
+ // +" documentType: "+documentType);
}
} catch (Throwable t){
- System.out.println("====Error finding objectNumberProperty: "+ServiceBindingUtils.OBJ_NUMBER_PROP+"="+propName
+ logger.error("====Error finding objectNumberProperty: "+ServiceBindingUtils.OBJ_NUMBER_PROP+"="+propName
+" not found in itemDocType: "+itemDocType+" inner: "+t.getMessage());
}
} else {