<?xml version="1.0" encoding="UTF-8"?>\r
<xmlReplay>\r
- <!-- \r
- testGroup ID="person" is not live. It works, but may not clean up correctly. \r
- For now, use ID="updatePerson"\r
- -->\r
- <testGroup ID="AuthRefs" autoDeletePOSTS="true">\r
- <test ID="PersonAuth1" auth="admin@core.collectionspace.org">\r
- <method>POST</method>\r
- <uri>/cspace-services/personauthorities/</uri>\r
- <filename>authrefs/newPersonAuthority.xml</filename>\r
- </test>\r
- <test ID="Person1">\r
- <method>POST</method>\r
- <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/</uri>\r
- <filename>authrefs/newPerson1.xml</filename>\r
- </test>\r
- <test ID="Person2">\r
- <method>POST</method>\r
- <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/</uri>\r
- <filename>authrefs/newPerson2.xml</filename>\r
- </test>\r
-\r
- <test ID="loanout1" auth="test">\r
- <method>POST</method>\r
- <uri>/cspace-services/loansout/</uri>\r
- <filename>authrefs/loanout.xml</filename>\r
- <vars>\r
- <var ID="loannum">42</var>\r
- <var ID="person">${Person1.CSID}</var>\r
- </vars>\r
- </test>\r
-\r
- <test ID="loanout2" auth="test">\r
- <method>POST</method>\r
- <uri>/cspace-services/loansout/</uri>\r
- <filename>authrefs/loanout.xml</filename>\r
- <vars>\r
- <var ID="loannum">69</var>\r
- <var ID="person">${Person2.CSID}</var>\r
- </vars>\r
- </test>\r
-\r
- <test ID="UpdatePerson1">\r
- <method>PUT</method>\r
- <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}</uri>\r
- <filename>authrefs/updatePerson1.xml</filename>\r
- </test>\r
-\r
- <test ID="UpdatePerson2">\r
- <method>PUT</method>\r
- <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person2.CSID}</uri>\r
- <filename>authrefs/updatePerson2.xml</filename>\r
- </test>\r
- </testGroup>\r
+ <!-- \r
+ testGroup ID="person" is not live. It works, but may not clean up correctly. \r
+ For now, use ID="updatePerson"\r
+ -->\r
+ <testGroup ID="AuthRefs" autoDeletePOSTS="true">\r
+ <test ID="PersonAuth1" auth="admin@core.collectionspace.org">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/personauthorities/</uri>\r
+ <filename>authrefs/newPersonAuthority.xml</filename>\r
+ </test>\r
+ <test ID="Person1">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/</uri>\r
+ <filename>authrefs/newPerson1.xml</filename>\r
+ </test>\r
+ <test ID="Person2">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/</uri>\r
+ <filename>authrefs/newPerson2.xml</filename>\r
+ </test>\r
\r
+ <test ID="GetPerson1">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}</uri>\r
+ </test>\r
+\r
+ <test ID="GetPerson2">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person2.CSID}</uri>\r
+ </test>\r
+\r
+ <test ID="loanout1" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">42</var>\r
+ <var ID="person">${GetPerson1.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout2" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">102</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout3" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">103</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout4" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">104</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout5" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">105</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout6" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">106</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout7" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">107</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout8" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">108</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout9" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">109</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="loanout10" auth="test">\r
+ <method>POST</method>\r
+ <uri>/cspace-services/loansout/</uri>\r
+ <filename>authrefs/loanout.xml</filename>\r
+ <vars>\r
+ <var ID="loannum">110</var>\r
+ <var ID="person">${GetPerson2.got("//refName")}</var>\r
+ </vars>\r
+ </test>\r
+\r
+ <test ID="UpdatePerson1">\r
+ <method>PUT</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}</uri>\r
+ <filename>authrefs/updatePerson1.xml</filename>\r
+ </test>\r
+\r
+ <test ID="UpdatePerson2">\r
+ <method>PUT</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person2.CSID}</uri>\r
+ <filename>authrefs/updatePerson2.xml</filename>\r
+ </test>\r
+\r
+ <test ID="GetFirstUpdatedPerson">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}</uri>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <filename>authrefs/updatePerson1.xml</filename>\r
+ </response>\r
+ </test>\r
+\r
+ <test ID="GetSecondUpdatedPerson">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person2.CSID}</uri>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <filename>authrefs/updatePerson2.xml</filename>\r
+ </response>\r
+ </test>\r
+\r
+ <test ID="afterUpdateGetLoan1">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/loansout/${loanout1.CSID}</uri>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <label>loansout_common</label>\r
+ <filename>authrefs/res/loanout.res.xml</filename>\r
+ <vars>\r
+ <var ID="person">${GetFirstUpdatedPerson.got("//refName")}</var>\r
+ </vars>\r
+ </response>\r
+ </test>\r
+ \r
+ <test ID="afterUpdateGetLoan2">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/loansout/${loanout2.CSID}</uri>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <label>loansout_common</label>\r
+ <filename>authrefs/res/loanout.res.xml</filename>\r
+ <vars>\r
+ <var ID="person">${GetSecondUpdatedPerson.got("//refName")}</var>\r
+ </vars>\r
+ </response>\r
+ </test>\r
+ <test ID="afterUpdateGetLoan5">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/loansout/${loanout5.CSID}</uri>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <label>loansout_common</label>\r
+ <filename>authrefs/res/loanout.res.xml</filename>\r
+ <vars>\r
+ <var ID="person">${GetSecondUpdatedPerson.got("//refName")}</var>\r
+ </vars>\r
+ </response>\r
+ </test>\r
+\r
+ <test ID="afterUpdateGetLoan9">\r
+ <method>GET</method>\r
+ <uri>/cspace-services/loansout/${loanout9.CSID}</uri>\r
+ <response>\r
+ <expected level="ADDOK" />\r
+ <label>loansout_common</label>\r
+ <filename>authrefs/res/loanout.res.xml</filename>\r
+ <vars>\r
+ <var ID="person">${GetSecondUpdatedPerson.got("//refName")}</var>\r
+ </vars>\r
+ </response>\r
+ </test>\r
+\r
+\r
+ </testGroup>\r
</xmlReplay>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<document name="loansout">
+ <ns2:loansout_common xmlns:ns2="http://collectionspace.org/services/loanout" xmlns:ns3="http://collectionspace.org/services/jaxb">
+ <borrowersContact>${person}</borrowersContact>
+ </ns2:loansout_common>
+</document>
+
<run controlFile="batch/batch.xml" />\r
<run controlFile="report/report.xml" />\r
<run controlFile="vocabulary/vocabulary.xml" testGroup="TestOrder" />\r
+ <run controlFile="authrefs/authrefs.xml" testGroup="AuthRefs" />\r
+\r
\r
</xmlReplayMaster>\r
\r
DocumentModel docModel = docWrapper.getWrappedObject();
String refName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
+ // Could be smarter about using the list from above, and/or allowing multiple
+ ArrayList<String> serviceTypes = new ArrayList<String>(1);
+ serviceTypes.add(serviceType);
+
authRefDocList = RefNameServiceUtils.getAuthorityRefDocs(ctx,
repoClient,
- serviceType,
+ serviceTypes,
refName,
getRefPropName(),
myFilter.getPageSize(), myFilter.getStartPage(), true /*computeTotal*/);
import org.nuxeo.ecm.core.api.ClientException;\r
import org.nuxeo.ecm.core.api.DocumentModel;\r
import org.nuxeo.ecm.core.api.DocumentModelList;\r
+import org.nuxeo.ecm.core.api.model.Property;\r
+import org.nuxeo.ecm.core.api.model.PropertyException;\r
+import org.nuxeo.ecm.core.api.model.impl.primitives.StringProperty;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
import org.collectionspace.services.common.ServiceMain;\r
import org.collectionspace.services.common.context.ServiceContext;\r
+import org.collectionspace.services.common.api.Tools;\r
import org.collectionspace.services.common.authorityref.AuthorityRefDocList;\r
import org.collectionspace.services.common.authorityref.AuthorityRefList;\r
import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
import org.collectionspace.services.common.document.DocumentUtils;\r
import org.collectionspace.services.common.document.DocumentWrapper;\r
import org.collectionspace.services.common.repository.RepositoryClient;\r
+import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;\r
import org.collectionspace.services.common.service.ServiceBindingType;\r
import org.collectionspace.services.jaxb.AbstractCommonList;\r
import org.collectionspace.services.nuxeo.util.NuxeoUtils;\r
public class RefNameServiceUtils {\r
\r
private static final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
+ \r
+ private static ArrayList<String> refNameServiceTypes = null;\r
\r
public static AuthorityRefDocList getAuthorityRefDocs(ServiceContext ctx,\r
RepositoryClient repoClient,\r
- String serviceType,\r
+ List<String> serviceTypes,\r
String refName,\r
String refPropName,\r
int pageSize, int pageNum, boolean computeTotal) throws DocumentException, DocumentNotFoundException {\r
commonList.setPageSize(pageSize);\r
List<AuthorityRefDocList.AuthorityRefDocItem> list =\r
wrapperList.getAuthorityRefDocItem();\r
+ \r
+ Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
+ Map<String, Map<String, String>> authRefFieldsByService = new HashMap<String, Map<String, String>>();\r
+\r
+ DocumentModelList docList = findAuthorityRefDocs(ctx, repoClient, serviceTypes, refName, refPropName,\r
+ queriedServiceBindings, authRefFieldsByService, pageSize, pageNum, computeTotal);\r
+\r
+ if (docList == null) { // found no authRef fields - nothing to process\r
+ return wrapperList;\r
+ }\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
+ int nRefsFound = processRefObjsDocList(docList, refName, queriedServiceBindings, authRefFieldsByService,\r
+ list, null);\r
+ if(logger.isDebugEnabled() && (nRefsFound < docList.size())) {\r
+ logger.debug("Internal curiosity: got fewer matches of refs than # docs matched...");\r
+ }\r
+ return wrapperList;\r
+ }\r
+ \r
+ private static ArrayList<String> getRefNameServiceTypes() {\r
+ if(refNameServiceTypes == null) {\r
+ refNameServiceTypes = new ArrayList<String>();\r
+ refNameServiceTypes.add(ServiceBindingUtils.SERVICE_TYPE_AUTHORITY);\r
+ refNameServiceTypes.add(ServiceBindingUtils.SERVICE_TYPE_OBJECT);\r
+ refNameServiceTypes.add(ServiceBindingUtils.SERVICE_TYPE_PROCEDURE);\r
+ }\r
+ return refNameServiceTypes;\r
+ }\r
+ \r
+ public static int updateAuthorityRefDocs(ServiceContext ctx,\r
+ RepositoryClient repoClient,\r
+ String oldRefName,\r
+ String newRefName,\r
+ String refPropName ) {\r
+ Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
+ Map<String, Map<String, String>> authRefFieldsByService = new HashMap<String, Map<String, String>>();\r
+ int nRefsFound = 0;\r
+ if(!(repoClient instanceof RepositoryJavaClientImpl)) {\r
+ throw new InternalError("updateAuthorityRefDocs() called with unknown repoClient type!");\r
+ }\r
+ try {\r
+ final int pageSize = 100; // Seems like a good value - no real data to set this well.\r
+ int pageNumProcessed = 1;\r
+ while(true) { // Keep looping until we find all the refs.\r
+ logger.debug("updateAuthorityRefDocs working on page: "+pageNumProcessed);\r
+ // Note that we always ask the Repo for the first page, since each page we process\r
+ // should not be found in successive searches.\r
+ DocumentModelList docList = findAuthorityRefDocs(ctx, repoClient, getRefNameServiceTypes(), oldRefName, refPropName,\r
+ queriedServiceBindings, authRefFieldsByService, pageSize, 0, false);\r
+ \r
+ if((docList == null) // found no authRef fields - nothing to do\r
+ || (docList.size() == 0)) { // No more to handle\r
+ logger.debug("updateAuthorityRefDocs no more results");\r
+ break;\r
+ }\r
+ logger.debug("updateAuthorityRefDocs curr page result list size: "+docList.size());\r
+ int nRefsFoundThisPage = processRefObjsDocList(docList, oldRefName, queriedServiceBindings, authRefFieldsByService,\r
+ null, newRefName);\r
+ if(nRefsFoundThisPage>0) {\r
+ ((RepositoryJavaClientImpl)repoClient).saveDocListWithoutHandlerProcessing(ctx, docList, true);\r
+ nRefsFound += nRefsFoundThisPage;\r
+ }\r
+ pageNumProcessed++;\r
+ }\r
+ } catch(Exception e) {\r
+ logger.error("Internal error updating the AuthorityRefDocs: " + e.getLocalizedMessage());\r
+ logger.debug(Tools.errorToString(e, true));\r
+ }\r
+ logger.debug("updateAuthorityRefDocs replaced a total of: "+nRefsFound);\r
+ return nRefsFound;\r
+ }\r
+ \r
+ private static DocumentModelList findAuthorityRefDocs(ServiceContext ctx,\r
+ RepositoryClient repoClient,\r
+ List<String> serviceTypes,\r
+ String refName,\r
+ String refPropName,\r
+ Map<String, ServiceBindingType> queriedServiceBindings,\r
+ Map<String, Map<String, String>> authRefFieldsByService,\r
+ int pageSize, int pageNum, boolean computeTotal) throws DocumentException, DocumentNotFoundException {\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
+ // We need to get all the procedures, authorities, and objects.\r
+ List<ServiceBindingType> servicebindings = tReader.getServiceBindingsByType(ctx.getTenantId(), serviceTypes);\r
if (servicebindings == null || servicebindings.isEmpty()) {\r
logger.error("RefNameServiceUtils.getAuthorityRefDocs: No services bindings found, cannot proceed!");\r
return null;\r
// TODO What if they are already escaped?\r
String escapedRefName = refName.replaceAll("'", "\\\\'");\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, refPropName, docTypes, servicebindings, \r
queriedServiceBindings, authRefFieldsByService );\r
if (query == null) { // found no authRef fields - nothing to query\r
- return wrapperList;\r
+ return null;\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
+ return docList;\r
}\r
\r
private static String computeWhereClauseForAuthorityRefDocs(\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
+ * If list is null, and newRefName is non-null, then processing means replacing and updating. \r
+ * If processing/updating, this must be called in teh context of an open session, and caller\r
+ * must release Session after calling this.\r
+ * \r
*/\r
- private static void processRefObjsDocList(DocumentModelList docList,\r
+ private static int processRefObjsDocList(\r
+ 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
+ if(newAuthorityRefName==null) {\r
+ if(list==null) {\r
+ throw new InternalError("processRefObjsDocList() called with neither an itemList nor a new RefName!");\r
+ }\r
+ } else if(list!=null) {\r
+ throw new InternalError("processRefObjsDocList() called with both an itemList and a new RefName!");\r
+ }\r
+\r
Iterator<DocumentModel> iter = docList.iterator();\r
+ int nRefsFoundTotal = 0;\r
while (iter.hasNext()) {\r
DocumentModel docModel = iter.next();\r
AuthorityRefDocList.AuthorityRefDocItem ilistItem;\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
+ // out which field(s) matched this.\r
Map<String,String> matchingAuthRefFields = authRefFieldsByService.get(docType);\r
if (matchingAuthRefFields == null || matchingAuthRefFields.isEmpty()) {\r
throw new RuntimeException(\r
String authRefAncestorField = "";\r
String authRefDescendantField = "";\r
String sourceField = "";\r
- boolean fRefFound = false;\r
+ int nRefsFoundInDoc = 0;\r
// Use this if we go to qualified field names\r
for (String path : matchingAuthRefFields.keySet()) {\r
try {\r
// This is the field name we show in the return info\r
+ // Returned as a schema-qualified property path\r
authRefAncestorField = (String) matchingAuthRefFields.get(path);\r
// This is the qualified field we have to get from the doc model\r
authRefDescendantField = DocumentUtils.getDescendantOrAncestor(path);\r
// The ancestor field is part-schema (tablename) qualified\r
- String[] strings = authRefAncestorField.split(":");\r
- if (strings.length != 2) {\r
- throw new RuntimeException(\r
- "getAuthorityRefDocs: Bad configuration of path to authority reference field.");\r
- }\r
+ //String[] strings = authRefAncestorField.split(":");\r
+ //if (strings.length != 2) {\r
+ // throw new RuntimeException(\r
+ // "getAuthorityRefDocs: Bad configuration of path to authority reference field.");\r
+ //}\r
// strings[0] holds a schema name, such as "intakes_common"\r
//\r
// strings[1] holds:\r
// field, such as "fieldCollector".\r
// TODO - if the value is not simple, or repeating scalar, need a more\r
// sophisticated fetch. \r
- Object fieldValue = docModel.getProperty(strings[0], strings[1]);\r
- // We cannot be sure why we have this doc, so look for matches\r
- boolean fRefMatches = refNameFoundInField(refName, fieldValue);\r
- if (fRefMatches) {\r
+ // Change this to an XPath model\r
+ //Object fieldValue = docModel.getProperty(strings[0], strings[1]);\r
+ // This will have to handle repeating complex fields by iterating over the possibilities\r
+ // and finding the one that matches.\r
+ Property fieldValue = docModel.getProperty(authRefAncestorField);\r
+ // We know this doc should have a match somewhere, but it may not be in this field\r
+ // If we are just building up the refItems, then it is enough to know we found a match.\r
+ // If we are patching refName values, then we have to replace each match.\r
+ int nRefsMatchedInField = refNameFoundInField(refName, fieldValue, newAuthorityRefName);\r
+ if (nRefsMatchedInField > 0) {\r
sourceField = authRefDescendantField;\r
// Handle multiple fields matching in one Doc. See CSPACE-2863.\r
- if(fRefFound) {\r
+ if(nRefsFoundInDoc > 0) {\r
// We already added ilistItem, so we need to clone that and add again\r
if(ilistItem != null) {\r
ilistItem = cloneAuthRefDocItem(ilistItem, sourceField);\r
if(ilistItem != null) {\r
ilistItem.setSourceField(sourceField);\r
}\r
- fRefFound = true;\r
}\r
if(ilistItem != null) {\r
list.add(ilistItem);\r
}\r
+ nRefsFoundInDoc += nRefsMatchedInField;\r
}\r
\r
} catch (ClientException ce) {\r
"getAuthorityRefDocs: Problem fetching: " + sourceField, ce);\r
}\r
}\r
- if (!fRefFound) {\r
+ if (nRefsFoundInDoc == 0) {\r
throw new RuntimeException(\r
"getAuthorityRefDocs: Could not find refname in object:"\r
+ docType + ":" + NuxeoUtils.getCsid(docModel));\r
}\r
+ nRefsFoundTotal += nRefsFoundInDoc;\r
}\r
-\r
+ return nRefsFoundTotal;\r
}\r
\r
private static AuthorityRefDocList.AuthorityRefDocItem cloneAuthRefDocItem(\r
\r
/*\r
* Identifies whether the refName was found in the supplied field.\r
+ * If passed a new RefName, will set that into fields in which the old one was found.\r
*\r
* Only works for:\r
* * Scalar fields\r
* * Structured fields (complexTypes)\r
* * Repeatable structured fields (repeatable complexTypes)\r
*/\r
- private static boolean refNameFoundInField(String refName, Object fieldValue) {\r
-\r
- boolean result = false;\r
- if (fieldValue instanceof List) {\r
- List<String> fieldValueList = (List) fieldValue;\r
- for (String listItemValue : fieldValueList) {\r
- if (refName.equalsIgnoreCase(listItemValue)) {\r
- result = true;\r
- break;\r
- }\r
-\r
- }\r
- } else if (fieldValue instanceof String){\r
- if (refName.equalsIgnoreCase((String)fieldValue)) {\r
- result = true;\r
- }\r
- }\r
- return result;\r
+ private static int refNameFoundInField(String oldRefName, Property fieldValue, String newRefName) {\r
+ int nFound = 0;\r
+ if (fieldValue instanceof List) {\r
+ List<Property> fieldValueList = (List) fieldValue;\r
+ for (Property listItemValue : fieldValueList) {\r
+ try {\r
+ if ((listItemValue instanceof StringProperty)\r
+ && oldRefName.equalsIgnoreCase((String)listItemValue.getValue())) {\r
+ nFound++;\r
+ if(newRefName!=null) {\r
+ fieldValue.setValue(newRefName);\r
+ } else {\r
+ // We cannot quit after the first, if we are replacing values.\r
+ // If we are just looking (not replacing), finding one is enough.\r
+ break;\r
+ }\r
+ }\r
+ } catch( PropertyException pe ) {}\r
+ }\r
+ } else {\r
+ try {\r
+ if ((fieldValue instanceof StringProperty)\r
+ && oldRefName.equalsIgnoreCase((String)fieldValue.getValue())) {\r
+ nFound++;\r
+ if(newRefName!=null) {\r
+ fieldValue.setValue(newRefName);\r
+ }\r
+ }\r
+ } catch( PropertyException pe ) {}\r
+ }\r
+ return nFound;\r
}\r
}\r
\r
import org.collectionspace.services.common.api.RefName;
import org.collectionspace.services.common.api.Tools;
import org.collectionspace.services.common.context.MultipartServiceContext;
+import org.collectionspace.services.common.context.ServiceBindingUtils;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.document.DocumentWrapperImpl;
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);
+ if(logger.isDebugEnabled()) {
+ String eol = System.getProperty("line.separator");
+ logger.debug("Need to find and update references to Item."+eol
+ +" Old refName" + oldRefNameOnUpdate + eol
+ +" New refName" + newRefNameOnUpdate);
+ }
+ ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
+ RepositoryClient repoClient = getRepositoryClient(ctx);
+ // HACK - this should be defined for each handler, as with
+ // AuthorityResource.getRefPropName()
+ String refNameProp = ServiceBindingUtils.AUTH_REF_PROP;
+
+ int nUpdated = RefNameServiceUtils.updateAuthorityRefDocs(ctx, repoClient,
+ oldRefNameOnUpdate, newRefNameOnUpdate, refNameProp );
+ if(logger.isDebugEnabled()) {
+ logger.debug("Updated "+nUpdated+" instances of oldRefName to newRefName");
+ }
}
}
throws Exception {
Map<String, Object> unQObjectProperties = super.extractPart(docModel, schema, partMeta);
- // Add the CSID to the common part
+ // Add the CSID to the common part, since they may have fetched via the shortId.
if (partMeta.getLabel().equalsIgnoreCase(authorityItemCommonSchemaName)) {
String csid = getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
unQObjectProperties.put("csid", csid);
<!-- <types:item><types:key>localeLanguage</types:key><types:value>da</types:value></types:item> -->
</tenant:properties>
<!-- begin idgenerators service meta-data -->
- <tenant:serviceBindings id="idgenerators" name="idgenerators" version="0.1">
+ <tenant:serviceBindings id="idgenerators" name="idgenerators" type="utility" version="0.1">
<!-- other URI paths using which this service could be accessed -->
</tenant:serviceBindings>
<!-- end idgenerator service meta-data -->
<!-- begin id service meta-data -->
- <tenant:serviceBindings id="id" name="id" version="0.1">
+ <tenant:serviceBindings id="id" name="id" type="utility" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/idgenerators/*/ids
</tenant:serviceBindings>
<!--end collectionobject service meta-data -->
<!-- begin blob service meta-data -->
+ <!-- This should likely be type="object" -->
<tenant:serviceBindings id="Blobs" name="Blobs" type="procedure" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/blobs/*/workflow/</service:uriPath>
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
</tenant:serviceBindings>
<!-- end imports service meta-data -->
<!-- begin media service meta-data -->
- <tenant:serviceBindings id="Media" name="Media" type="procedure" version="0.1">
+ <!-- This should likely be type="object" -->
+ <tenant:serviceBindings id="Media" name="Media" type="procedure" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/media/*/workflow/</service:uriPath>
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.media.nuxeo.MediaDocumentModelHandler</service:documentHandler>
</tenant:serviceBindings>
<!-- end report service meta-data -->
<!-- begin vocabulary service meta-data -->
- <tenant:serviceBindings id="Vocabularies" name="Vocabularies" version="0.1">
+ <tenant:serviceBindings id="Vocabularies" name="Vocabularies" type="utility" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/vocabularies/*/workflow/</service:uriPath>
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/vocabularies/*/items/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
Note there is no Vocabularyitem service, but there is a
Repository workspace so we have to configure that.
-->
- <tenant:serviceBindings id="Vocabularyitems" name="Vocabularyitems" version="0.1">
+ <tenant:serviceBindings id="Vocabularyitems" name="Vocabularyitems" type="authority" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/vocabularyitems/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
<!--
</tenant:serviceBindings>
<!-- end vocabulary service meta-data -->
<!-- begin orgauthority service meta-data -->
- <tenant:serviceBindings id="Orgauthorities" name="Orgauthorities" version="0.1">
+ <tenant:serviceBindings id="Orgauthorities" name="Orgauthorities" type="utility" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/orgauthorities/*/workflow/</service:uriPath>
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/orgauthorities/*/items/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
Note there is no Organization service, but there is a
Repository workspace so we have to configure that.
-->
- <tenant:serviceBindings id="Organizations" name="Organizations" version="0.1">
+ <tenant:serviceBindings id="Organizations" name="Organizations" type="authority" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/orgauthorities/*/items/
</tenant:serviceBindings>
<!-- end organization service meta-data -->
<!-- begin personauthority service meta-data -->
- <tenant:serviceBindings id="Personauthorities" name="Personauthorities" version="0.1">
+ <tenant:serviceBindings id="Personauthorities" name="Personauthorities" type="utility" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/personauthorities/*/workflow/</service:uriPath>
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/personauthorities/*/items/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
Note there is no Person service, but there is a
Repository workspace so we have to configure that.
-->
- <tenant:serviceBindings id="Persons" name="Persons" version="0.1">
+ <tenant:serviceBindings id="Persons" name="Persons" type="authority" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/personauthorities/*/items/
</service:properties>
<service:object xmlns:service="http://collectionspace.org/services/common/service" id="1" name="Person" version="0.1">
<service:part id="0" control_group="Managed" versionable="true" auditable="false" label="persons-system" updated="" order="0">
+ <service:content contentType="application/xml">
+ <service:xmlContent namespaceURI="http://collectionspace.org/services/common/system" schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd" />
+ </service:content>
+ </service:part>
+ <service:part id="1" control_group="Managed" versionable="true" auditable="false" label="persons_common" updated="" order="1">
+ <service:content contentType="application/xml">
+ <service:xmlContent namespaceURI="http://collectionspace.org/services/person" schemaLocation="http://collectionspace.org/services/person http://services.collectionspace.org/person/persons_common.xsd" />
+ </service:content>
<service:properties>
<!-- Place Authority reference -->
<types:item xmlns:types="http://collectionspace.org/services/common/types">
</types:item>
-->
</service:properties>
- <service:content contentType="application/xml">
- <service:xmlContent namespaceURI="http://collectionspace.org/services/common/system" schemaLocation="http://collectionspace.org/services/common/system http://collectionspace.org/services/common/system/system-response.xsd" />
- </service:content>
- </service:part>
- <service:part id="1" control_group="Managed" versionable="true" auditable="false" label="persons_common" updated="" order="1">
- <service:content contentType="application/xml">
- <service:xmlContent namespaceURI="http://collectionspace.org/services/person" schemaLocation="http://collectionspace.org/services/person http://services.collectionspace.org/person/persons_common.xsd" />
- </service:content>
</service:part>
<service:part id="2" control_group="Managed" versionable="true" auditable="false" label="collectionspace_core" updated="" order="2">
<service:content contentType="application/xml">
</tenant:serviceBindings>
<!-- end person service meta-data -->
<!-- begin locationauthority service meta-data -->
- <tenant:serviceBindings id="Locationauthorities" name="Locationauthorities" version="0.1">
+ <tenant:serviceBindings id="Locationauthorities" name="Locationauthorities" type="utility" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/locationauthorities/*/workflow/</service:uriPath>
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/locationauthorities/*/items/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
Note there is no Location service, but there is a
Repository workspace so we have to configure that.
-->
- <tenant:serviceBindings id="Locations" name="Locations" version="0.1">
+ <tenant:serviceBindings id="Locations" name="Locations" type="authority" version="0.1">
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.location.nuxeo.LocationDocumentModelHandler</service:documentHandler>
<service:DocHandlerParams xmlns:service="http://collectionspace.org/services/common/service">
</tenant:serviceBindings>
<!-- end location service meta-data -->
<!-- begin taxonomyauthority service meta-data -->
- <tenant:serviceBindings id="Taxonomyauthority" name="Taxonomyauthority" version="0.1">
+ <tenant:serviceBindings id="Taxonomyauthority" name="Taxonomyauthority" type="utility" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/taxonomyauthority/*/workflow/</service:uriPath>
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/taxonomyauthority/*/items/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
Note there is no Taxon service, but there is a
Repository workspace so we have to configure that.
-->
- <tenant:serviceBindings id="Taxon" name="Taxon" version="0.1">
+ <tenant:serviceBindings id="Taxon" name="Taxon" type="authority" version="0.1">
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.taxonomy.nuxeo.TaxonDocumentModelHandler</service:documentHandler>
<service:DocHandlerParams xmlns:service="http://collectionspace.org/services/common/service">
</tenant:serviceBindings>
<!-- end acquisition service meta-data -->
<!-- begin relation service meta-data -->
- <tenant:serviceBindings id="Relations" name="Relations" version="0.1">
+ <tenant:serviceBindings id="Relations" name="Relations" type="utility" version="0.1">
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/relations/*/workflow/</service:uriPath>
<!-- other URI paths using which this service could be accessed -->
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
</tenant:serviceBindings>
<!-- end relation service meta-data -->
<!-- begin account service meta-data -->
- <tenant:serviceBindings id="Accounts" name="Accounts" version="0.1">
+ <tenant:serviceBindings id="Accounts" name="Accounts" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.account.storage.AccountDocumentHandler</service:documentHandler>
<service:DocHandlerParams xmlns:service="http://collectionspace.org/services/common/service">
</tenant:serviceBindings>
<!-- end account service meta-data -->
<!-- begin dimension service meta-data -->
- <tenant:serviceBindings id="Dimensions" name="Dimensions" version="0.1">
+ <tenant:serviceBindings id="Dimensions" name="Dimensions" type="utility" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<service:uriPath xmlns:service="http://collectionspace.org/services/common/service">/dimensions/*/workflow/</service:uriPath>
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
</tenant:serviceBindings>
<!-- end dimension service meta-data -->
<!-- begin contact service meta-data -->
- <tenant:serviceBindings id="Contacts" name="Contacts" version="0.1">
+ <tenant:serviceBindings id="Contacts" name="Contacts" type="utility" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/personauthorities/*/items/*/contacts
</tenant:serviceBindings>
<!-- end contact service meta-data -->
<!-- begin note service meta-data -->
- <tenant:serviceBindings id="Notes" name="Notes" version="0.1">
+ <tenant:serviceBindings id="Notes" name="Notes" type="utility" version="0.1">
<service:repositoryDomain xmlns:service="http://collectionspace.org/services/common/service">default-domain</service:repositoryDomain>
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.note.nuxeo.NoteDocumentModelHandler</service:documentHandler>
<service:object xmlns:service="http://collectionspace.org/services/common/service" name="CSNote" version="0.1">
</tenant:serviceBindings>
<!-- end note service meta-data -->
<!-- begin role service meta-data -->
- <tenant:serviceBindings id="authorization/roles" name="authorization/roles" version="0.1">
+ <tenant:serviceBindings id="authorization/roles" name="authorization/roles" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.authorization.storage.RoleDocumentHandler</service:documentHandler>
<service:validatorHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.authorization.storage.RoleValidatorHandler</service:validatorHandler>
</tenant:serviceBindings>
<!-- end role service meta-data -->
<!-- begin permission service meta-data -->
- <tenant:serviceBindings id="authorization/permissions" name="authorization/permissions" version="0.1">
+ <tenant:serviceBindings id="authorization/permissions" name="authorization/permissions" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<service:documentHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.authorization.storage.PermissionDocumentHandler</service:documentHandler>
<service:validatorHandler xmlns:service="http://collectionspace.org/services/common/service">org.collectionspace.services.authorization.storage.PermissionValidatorHandler</service:validatorHandler>
<!-- begin permission-role service meta-data -->
<!-- the following service is same as authorization/roles/permroles service -->
<!-- except that it is available as a sub resource of the permission service -->
- <tenant:serviceBindings id="authorization/permissions/permroles" name="authorization/permissions/permroles" version="0.1">
+ <tenant:serviceBindings id="authorization/permissions/permroles" name="authorization/permissions/permroles" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/authorization/permissions/*/permroles/
</tenant:serviceBindings>
<!-- end permission-role service meta-data -->
<!-- begin account-role service meta-data -->
- <tenant:serviceBindings id="accounts/accountroles" name="accounts/accountroles" version="0.1">
+ <tenant:serviceBindings id="accounts/accountroles" name="accounts/accountroles" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/accounts/*/accountroles/
<!-- begin role-permission service meta-data -->
<!-- the following service is same as authorization/permissions/permroles service -->
<!-- except that it is available as a sub resource of the role service -->
- <tenant:serviceBindings id="authorization/roles/permroles" name="authorization/roles/permroles" version="0.1">
+ <tenant:serviceBindings id="authorization/roles/permroles" name="authorization/roles/permroles" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/authorization/roles/*/permroles/
<!-- begin role-account service meta-data -->
<!-- the following service is same as account/accountroles service -->
<!-- except that it is available as a sub resource of the role service -->
- <tenant:serviceBindings id="authorization/roles/accountroles" name="authorization/roles/accountroles" version="0.1">
+ <tenant:serviceBindings id="authorization/roles/accountroles" name="authorization/roles/accountroles" type="security" version="0.1">
<!-- other URI paths using which this service could be accessed -->
<!-- <service:uriPath xmlns:service='http://collectionspace.org/services/common/service'>
/authorization/roles/*/accountroles/
* @return
*/
public List<ServiceBindingType> getServiceBindingsByType(
- String tenantId, String serviceType) {
+ String tenantId, List<String> serviceTypes) {
ArrayList<ServiceBindingType> list = null;
TenantBindingType tenant = tenantBindings.get(tenantId);
if (tenant != null) {
for (ServiceBindingType sb : tenant.getServiceBindings()) {
- if (serviceType.equals(sb.getType())) {
+ if (serviceTypes.contains(sb.getType())) {
if (list == null) {
list = new ArrayList<ServiceBindingType>();
}
public static final String SERVICE_TYPE_PROP = "type";\r
public static final String SERVICE_TYPE_OBJECT = "object";\r
public static final String SERVICE_TYPE_PROCEDURE = "procedure";\r
+ public static final String SERVICE_TYPE_AUTHORITY = "authority";\r
+ public static final String SERVICE_TYPE_UTILITY = "utility";\r
+ public static final String SERVICE_TYPE_SECURITY = "security";\r
\r
public static String getTenantQualifiedDocType(String tenantId, String docType) {\r
String result = docType + ServiceContext.TENANT_SUFFIX + tenantId;\r
}
}
}
+
+ /**
+ * Save a documentModel to the Nuxeo repository, using the current session,
+ * bypassing the normal document handler processing (validation, etc.)
+ * NOTE: This should be called only in specific circumstances, e.g., to
+ * update known cached values like refNames. DO NOT USE this for any normal
+ * document processing.
+ * NOTE: Does not release session, as it should be called in a wider session context.
+ * Caller is responsible for releasing the session.
+ *
+ * @param ctx service context under which this method is invoked
+ * @param docModel the document to save
+ * @param fSaveSession if TRUE, will call CoreSession.save() to save accumulated changes.
+ * @throws DocumentException
+ */
+ public void saveDocWithoutHandlerProcessing(
+ ServiceContext ctx, DocumentModel docModel, boolean fSaveSession)
+ throws ClientException, DocumentException {
+ RepositoryInstance repoSession = null;
+ DocumentWrapper<DocumentModel> wrapDoc = null;
+
+ try {
+ repoSession = getRepositorySession();
+ repoSession.saveDocument(docModel);
+ if(fSaveSession)
+ repoSession.save();
+ } catch (ClientException ce) {
+ throw ce;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }
+ }
+
+
+ /**
+ * Save a list of documentModels to the Nuxeo repository, using the current session,
+ * bypassing the normal document handler processing (validation, etc.)
+ * NOTE: This should be called only in specific circumstances, e.g., to
+ * update known cached values like refNames. DO NOT USE this for any normal
+ * document processing.
+ * NOTE: Does not release session, as it should be called in a wider session context.
+ * Caller is responsible for releasing the session.
+ *
+ * @param ctx service context under which this method is invoked
+ * @param docModel the document to save
+ * @param fSaveSession if TRUE, will call CoreSession.save() to save accumulated changes.
+ * @throws DocumentException
+ */
+ public void saveDocListWithoutHandlerProcessing(
+ ServiceContext ctx, DocumentModelList docList, boolean fSaveSession)
+ throws ClientException, DocumentException {
+ RepositoryInstance repoSession = null;
+ DocumentWrapper<DocumentModel> wrapDoc = null;
+
+ try {
+ repoSession = getRepositorySession();
+ DocumentModel[] docModelArray = new DocumentModel[docList.size()];
+ repoSession.saveDocuments(docList.toArray(docModelArray));
+ if(fSaveSession)
+ repoSession.save();
+ } catch (ClientException ce) {
+ throw ce;
+ } catch (Exception e) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Caught exception ", e);
+ }
+ throw new DocumentException(e);
+ }
+ }
+
+
/**
* delete a document from the Nuxeo repository
String msg = "";
boolean invalid = false;
- // Validation specific to creates or updates
- if (action.equals(Action.CREATE)) {
- String shortId = personAuth.getShortIdentifier();
- // Per CSPACE-2215, shortIdentifier values that are null (missing)
- // oe the empty string are now legally accepted in create payloads.
- // In either of those cases, a short identifier will be synthesized from
- // a display name or supplied in another manner.
- if ((shortId != null) && (shortIdBadPattern.matcher(shortId).find())) {
- invalid = true;
- msg += "shortIdentifier must only contain standard word characters";
- }
- } else if (action.equals(Action.UPDATE)) {
+ if(personAuth != null) { // No guarantee that there is a common part in every post/update.
+ // Validation specific to creates or updates
+ if (action.equals(Action.CREATE)) {
+ String shortId = personAuth.getShortIdentifier();
+ // Per CSPACE-2215, shortIdentifier values that are null (missing)
+ // oe the empty string are now legally accepted in create payloads.
+ // In either of those cases, a short identifier will be synthesized from
+ // a display name or supplied in another manner.
+ if ((shortId != null) && (shortIdBadPattern.matcher(shortId).find())) {
+ invalid = true;
+ msg += "shortIdentifier must only contain standard word characters";
+ }
+ } else if (action.equals(Action.UPDATE)) {
+ }
}
if (invalid) {
String msg = "";
boolean invalid = false;
- // Validation occurring on both creates and updates
- String displayName = person.getDisplayName();
- if (!person.isDisplayNameComputed() && ((displayName == null) || displayName.trim().isEmpty())) {
- invalid = true;
- msg += "displayName must be non-null and non-blank if displayNameComputed is false!";
- }
-
- // Validation specific to creates or updates
- if (action.equals(Action.CREATE)) {
- String shortId = person.getShortIdentifier();
- // Per CSPACE-2215, shortIdentifier values that are null (missing)
- // oe the empty string are now legally accepted in create payloads.
- // In either of those cases, a short identifier will be synthesized from
- // a display name or supplied in another manner.
- if ((shortId != null) && (shortIdBadPattern.matcher(shortId).find())) {
- invalid = true;
- msg += "shortIdentifier must only contain standard word characters";
- }
- } else if (action.equals(Action.UPDATE)) {
+ if(person != null) { // No guarantee that there is a common part in every post/update.
+ // Validation occurring on both creates and updates
+ String displayName = person.getDisplayName();
+ if (!person.isDisplayNameComputed() && ((displayName == null) || displayName.trim().isEmpty())) {
+ invalid = true;
+ msg += "displayName must be non-null and non-blank if displayNameComputed is false!";
+ }
+
+ // Validation specific to creates or updates
+ if (action.equals(Action.CREATE)) {
+ String shortId = person.getShortIdentifier();
+ // Per CSPACE-2215, shortIdentifier values that are null (missing)
+ // oe the empty string are now legally accepted in create payloads.
+ // In either of those cases, a short identifier will be synthesized from
+ // a display name or supplied in another manner.
+ if ((shortId != null) && (shortIdBadPattern.matcher(shortId).find())) {
+ invalid = true;
+ msg += "shortIdentifier must only contain standard word characters";
+ }
+ } else if (action.equals(Action.UPDATE)) {
+ }
}
if (invalid) {