*/\r
public class RefNameServiceUtils {\r
\r
- private final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
+ private static final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
\r
public static AuthorityRefDocList getAuthorityRefDocs(ServiceContext ctx,\r
RepositoryClient repoClient,\r
AbstractCommonList commonList = (AbstractCommonList) wrapperList;\r
commonList.setPageNum(pageNum);\r
commonList.setPageSize(pageSize);\r
-\r
- \r
List<AuthorityRefDocList.AuthorityRefDocItem> list =\r
wrapperList.getAuthorityRefDocItem();\r
+\r
+ // Get the service bindings for this tenant\r
TenantBindingConfigReaderImpl tReader =\r
ServiceMain.getInstance().getTenantBindingConfigReader();\r
List<ServiceBindingType> servicebindings = tReader.getServiceBindingsByType(ctx.getTenantId(), serviceType);\r
if (servicebindings == null || servicebindings.isEmpty()) {\r
+ logger.error("RefNameServiceUtils.getAuthorityRefDocs: No services bindings found, cannot proceed!");\r
return null;\r
}\r
+ \r
// Need to escape the quotes in the refName\r
// TODO What if they are already escaped?\r
String escapedRefName = refName.replaceAll("'", "\\\\'");\r
-// String domain = \r
-// tReader.getTenantBinding(ctx.getTenantId()).getRepositoryDomain();\r
ArrayList<String> docTypes = new ArrayList<String>();\r
Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
Map<String, Map<String, String>> authRefFieldsByService = new HashMap<String, Map<String, String>>();\r
+ \r
+ String query = computeWhereClauseForAuthorityRefDocs(escapedRefName, docTypes, servicebindings, \r
+ queriedServiceBindings, authRefFieldsByService );\r
+ if (query == null) { // found no authRef fields - nothing to query\r
+ return wrapperList;\r
+ }\r
+ // Now we have to issue the search\r
+ DocumentWrapper<DocumentModelList> docListWrapper = repoClient.findDocs(ctx,\r
+ docTypes, query, pageSize, pageNum, computeTotal);\r
+ // Now we gather the info for each document into the list and return\r
+ DocumentModelList docList = docListWrapper.getWrappedObject();\r
+ // Set num of items in list. this is useful to our testing framework.\r
+ commonList.setItemsInPage(docList.size());\r
+ // set the total result size\r
+ commonList.setTotalItems(docList.totalSize());\r
+ \r
+ processRefObjsDocList(docList, refName, servicebindings,\r
+ queriedServiceBindings, authRefFieldsByService,\r
+ list, null);\r
+ return wrapperList;\r
+ }\r
+ \r
+ private static String computeWhereClauseForAuthorityRefDocs(\r
+ String escapedRefName,\r
+ ArrayList<String> docTypes,\r
+ List<ServiceBindingType> servicebindings,\r
+ Map<String, ServiceBindingType> queriedServiceBindings,\r
+ Map<String, Map<String, String>> authRefFieldsByService ) {\r
StringBuilder whereClause = new StringBuilder();\r
boolean fFirst = true;\r
List<String> authRefFieldPaths = new ArrayList<String>();\r
}\r
}\r
String whereClauseStr = whereClause.toString(); // for debugging\r
- if (fFirst) // found no authRef fields - nothing to query\r
- {\r
- return wrapperList;\r
+ if (fFirst) { // found no authRef fields - nothing to query\r
+ return null;\r
+ } else {\r
+ return whereClause.toString(); \r
}\r
- String fullQuery = whereClause.toString(); // for debug\r
- // Now we have to issue the search\r
- DocumentWrapper<DocumentModelList> docListWrapper = repoClient.findDocs(ctx,\r
- docTypes, whereClause.toString(), pageSize, pageNum, computeTotal);\r
- // Now we gather the info for each document into the list and return\r
- DocumentModelList docList = docListWrapper.getWrappedObject();\r
- // Set num of items in list. this is useful to our testing framework.\r
- commonList.setItemsInPage(docList.size());\r
- // set the total result size\r
- commonList.setTotalItems(docList.totalSize());\r
+ }\r
+ \r
+ /*\r
+ * Runs through the list of found docs, processing them. \r
+ * If list is non-null, then processing means gather the info for items.\r
+ * If list is null, and newRefName is non-null, then processing means replacing and updating.\r
+ */\r
+ private static void processRefObjsDocList(DocumentModelList docList,\r
+ String refName,\r
+ List<ServiceBindingType> servicebindings,\r
+ Map<String, ServiceBindingType> queriedServiceBindings,\r
+ Map<String, Map<String, String>> authRefFieldsByService,\r
+ List<AuthorityRefDocList.AuthorityRefDocItem> list, \r
+ String newAuthorityRefName) {\r
Iterator<DocumentModel> iter = docList.iterator();\r
while (iter.hasNext()) {\r
DocumentModel docModel = iter.next();\r
- AuthorityRefDocList.AuthorityRefDocItem ilistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
- String csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());\r
+ AuthorityRefDocList.AuthorityRefDocItem ilistItem;\r
+\r
String docType = docModel.getDocumentType().getName();\r
ServiceBindingType sb = queriedServiceBindings.get(docType);\r
if (sb == null) {\r
"getAuthorityRefDocs: No Service Binding for docType: " + docType);\r
}\r
String serviceContextPath = "/" + sb.getName().toLowerCase() + "/";\r
- // The id and URI are the same on all doctypes\r
- ilistItem.setDocId(csid);\r
- ilistItem.setUri(serviceContextPath + csid);\r
- ilistItem.setDocType(docType);\r
- ilistItem.setDocNumber(\r
- ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel));\r
- ilistItem.setDocName(\r
- ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel));\r
+ \r
+ if(list == null) {\r
+ ilistItem = null;\r
+ } else {\r
+ ilistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
+ String csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());\r
+ ilistItem.setDocId(csid);\r
+ ilistItem.setUri(serviceContextPath + csid);\r
+ // The id and URI are the same on all doctypes\r
+ ilistItem.setDocType(docType);\r
+ ilistItem.setDocNumber(\r
+ ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NUMBER_PROP, docModel));\r
+ ilistItem.setDocName(\r
+ ServiceBindingUtils.getMappedFieldInDoc(sb, ServiceBindingUtils.OBJ_NAME_PROP, docModel));\r
+ }\r
// Now, we have to loop over the authRefFieldsByService to figure\r
// out which field matched this. Ignore multiple matches.\r
Map<String,String> matchingAuthRefFields = authRefFieldsByService.get(docType);\r
// Handle multiple fields matching in one Doc. See CSPACE-2863.\r
if(fRefFound) {\r
// We already added ilistItem, so we need to clone that and add again\r
- ilistItem = cloneAuthRefDocItem(ilistItem, sourceField);\r
+ if(ilistItem != null) {\r
+ ilistItem = cloneAuthRefDocItem(ilistItem, sourceField);\r
+ }\r
} else {\r
- ilistItem.setSourceField(sourceField);\r
+ if(ilistItem != null) {\r
+ ilistItem.setSourceField(sourceField);\r
+ }\r
fRefFound = true;\r
}\r
- list.add(ilistItem);\r
+ if(ilistItem != null) {\r
+ list.add(ilistItem);\r
+ }\r
}\r
\r
} catch (ClientException ce) {\r
if (!fRefFound) {\r
throw new RuntimeException(\r
"getAuthorityRefDocs: Could not find refname in object:"\r
- + docType + ":" + csid);\r
+ + docType + ":" + NuxeoUtils.getCsid(docModel));\r
}\r
}\r
- return wrapperList;\r
+\r
}\r
\r
private static AuthorityRefDocList.AuthorityRefDocItem cloneAuthRefDocItem(\r
import org.collectionspace.services.common.service.ObjectPartType;
import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
import org.collectionspace.services.nuxeo.util.NuxeoUtils;
import org.collectionspace.services.relation.RelationResource;
*/
protected String inAuthority;
protected String authorityRefNameBase;
+
+ // Used to determine when the displayName changes as part of the update.
+ protected String oldDisplayNameOnUpdate = null;
+ protected String oldRefNameOnUpdate = null;
+ protected String newRefNameOnUpdate = null;
public AuthorityItemDocumentModelHandler(String authorityItemCommonSchemaName) {
this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
super.handleCreate(wrapDoc);
handleInAuthority(wrapDoc.getWrappedObject());
handleComputedDisplayNames(wrapDoc.getWrappedObject());
+ String displayName = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName,
+ AuthorityItemJAXBSchema.DISPLAY_NAME);
+ if(Tools.isEmpty(displayName)) {
+ logger.warn("Creating Authority Item with no displayName!");
+ }
// CSPACE-3178:
// Uncomment once debugged and App layer is read to integrate
// Experimenting with these uncommented now ...
*/
@Override
public void handleUpdate(DocumentWrapper<DocumentModel> wrapDoc) throws Exception {
+ // First, get a copy of the old displayName
+ oldDisplayNameOnUpdate = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName,
+ AuthorityItemJAXBSchema.DISPLAY_NAME);
+ oldRefNameOnUpdate = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName,
+ AuthorityItemJAXBSchema.REF_NAME);
super.handleUpdate(wrapDoc);
handleComputedDisplayNames(wrapDoc.getWrappedObject());
+ String newDisplayName = (String) wrapDoc.getWrappedObject().getProperty(authorityItemCommonSchemaName,
+ AuthorityItemJAXBSchema.DISPLAY_NAME);
+ if(newDisplayName != null && !newDisplayName.equals(oldDisplayNameOnUpdate)) {
+ // Need to update the refName, and then fix all references.
+ newRefNameOnUpdate = handleItemRefNameUpdateForDisplayName(wrapDoc.getWrappedObject(), newDisplayName);
+ } else {
+ // Mark as not needing attention in completeUpdate phase.
+ newRefNameOnUpdate = null;
+ oldRefNameOnUpdate = null;
+ }
}
/**
// Do nothing by default.
}
+ /**
+ * Handle refName updates for changes to display name.
+ * Assumes refName is already correct. Just ensures it is right.
+ *
+ * @param docModel the doc model
+ * @throws Exception the exception
+ */
+ protected String handleItemRefNameUpdateForDisplayName(DocumentModel docModel,
+ String newDisplayName) throws Exception {
+ //String suppliedRefName = (String) docModel.getProperty(authorityItemCommonSchemaName,
+ // AuthorityItemJAXBSchema.REF_NAME);
+ RefName.AuthorityItem authItem = RefName.AuthorityItem.parse(oldRefNameOnUpdate);
+ if(authItem == null) {
+ String err = "Authority Item has illegal refName: "+oldRefNameOnUpdate;
+ logger.debug(err);
+ throw new IllegalArgumentException(err);
+ }
+ authItem.displayName = newDisplayName;
+ String updatedRefName = authItem.toString();
+ docModel.setProperty(authorityItemCommonSchemaName, AuthorityItemJAXBSchema.REF_NAME, updatedRefName);
+ return updatedRefName;
+ }
+
+
+ /**
+ * Checks to see if the refName has changed, and if so,
+ * uses utilities to find all references and update them.
+ */
+ protected void handleItemRefNameReferenceUpdate() {
+ if(newRefNameOnUpdate != null && oldRefNameOnUpdate!= null) {
+ // We have work to do.
+ logger.debug("Need to find and update references to Item.");
+ logger.debug("Old refName" + oldRefNameOnUpdate);
+ logger.debug("New refName" + newRefNameOnUpdate);
+ }
+ }
+
+
private void handleDisplayNameAsShortIdentifier(DocumentModel docModel, String schemaName) throws Exception {
String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
String displayName = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
String suppliedRefName = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.REF_NAME);
// CSPACE-3178:
// Temporarily accept client-supplied refName values, rather than always generating such values.
- // Remove the surrounding 'if' statement when clients should no longer supply refName values.
- if (suppliedRefName == null || suppliedRefName.isEmpty()) {
+ // Remove first block and the surrounding 'if' statement when clients should no longer supply refName values.
+ if(!Tools.isEmpty(suppliedRefName) ) {
+ // Supplied refName must at least be legal
+ RefName.AuthorityItem item = RefName.AuthorityItem.parse(suppliedRefName);
+ if(item==null) {
+ logger.error("Passed refName for authority item not legal: "+suppliedRefName);
+ suppliedRefName = null; // Clear this and compute a new one below.
+ }
+ }
+ // Recheck, in case we cleared it for being illegal
+ if(Tools.isEmpty(suppliedRefName) ) {
String shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
String displayName = (String) docModel.getProperty(schemaName, AuthorityItemJAXBSchema.DISPLAY_NAME);
if (Tools.isEmpty(authorityRefBaseName)) {
ServiceContext ctx = getServiceContext();
PayloadOutputPart foo = (PayloadOutputPart) ctx.getProperty(RelationClient.SERVICE_COMMON_LIST_NAME);
((PoxPayloadOut) ctx.getOutput()).addPart(foo);
+ handleItemRefNameReferenceUpdate();
}
/** updateRelations strategy: