]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5359: Cleanup to improve clarity of program flow, variable naming, log statements.
authorAron Roberts <aron@socrates.berkeley.edu>
Tue, 10 Jul 2012 21:26:15 +0000 (14:26 -0700)
committerAron Roberts <aron@socrates.berkeley.edu>
Tue, 10 Jul 2012 21:26:15 +0000 (14:26 -0700)
services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java

index 17f35a645ecb3aacce02b8c92a9fdecff5fdc5b5..009605de287903120a36171a425ca3ceced4c67c 100644 (file)
@@ -1,25 +1,24 @@
 /**\r
- *  This document is a part of the source code and related artifacts\r
- *  for CollectionSpace, an open source collections management system\r
- *  for museums and related institutions:\r
-\r
- *  http://www.collectionspace.org\r
- *  http://wiki.collectionspace.org\r
-\r
- *  Copyright 2009 University of California at Berkeley\r
-\r
- *  Licensed under the Educational Community License (ECL), Version 2.0.\r
- *  You may not use this file except in compliance with this License.\r
-\r
- *  You may obtain a copy of the ECL 2.0 License at\r
-\r
- *  https://source.collectionspace.org/collection-space/LICENSE.txt\r
-\r
- *  Unless required by applicable law or agreed to in writing, software\r
- *  distributed under the License is distributed on an "AS IS" BASIS,\r
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- *  See the License for the specific language governing permissions and\r
- *  limitations under the License.\r
+ * This document is a part of the source code and related artifacts for\r
+ * CollectionSpace, an open source collections management system for museums and\r
+ * related institutions:\r
+ *\r
+ * http://www.collectionspace.org http://wiki.collectionspace.org\r
+ *\r
+ * Copyright 2009 University of California at Berkeley\r
+ *\r
+ * Licensed under the Educational Community License (ECL), Version 2.0. You may\r
+ * not use this file except in compliance with this License.\r
+ *\r
+ * You may obtain a copy of the ECL 2.0 License at\r
+ *\r
+ * https://source.collectionspace.org/collection-space/LICENSE.txt\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\r
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\r
+ * License for the specific language governing permissions and limitations under\r
+ * the License.\r
  */\r
 package org.collectionspace.services.common.vocabulary;\r
 \r
@@ -70,282 +69,314 @@ import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import com.sun.xml.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;\r
 \r
 /**\r
- * RefNameServiceUtils is a collection of services utilities related to refName usage.\r
+ * RefNameServiceUtils is a collection of services utilities related to refName\r
+ * usage.\r
  *\r
- * $LastChangedRevision: $\r
- * $LastChangedDate: $\r
+ * $LastChangedRevision: $ $LastChangedDate: $\r
  */\r
 public class RefNameServiceUtils {\r
 \r
-       public static class AuthRefConfigInfo {\r
-               public String getQualifiedDisplayName() {\r
-               return(Tools.isBlank(schema))?\r
-                               displayName:DocumentUtils.appendSchemaName(schema, displayName);\r
-               }\r
-               public String getDisplayName() {\r
-                       return displayName;\r
-               }\r
-               public void setDisplayName(String displayName) {\r
-                       this.displayName = displayName;\r
-               }\r
-               String displayName;\r
-               String schema;\r
-               public String getSchema() {\r
-                       return schema;\r
-               }\r
-               public void setSchema(String schema) {\r
-                       this.schema = schema;\r
-               }\r
-               public String getFullPath() {\r
-                       return fullPath;\r
-               }\r
-               public void setFullPath(String fullPath) {\r
-                       this.fullPath = fullPath;\r
-               }\r
-               String fullPath;\r
-               protected String[] pathEls;\r
-               public AuthRefConfigInfo(AuthRefConfigInfo arci) {\r
-                       this.displayName = arci.displayName;\r
-                       this.schema = arci.schema;\r
-                       this.fullPath = arci.fullPath;\r
-                       this.pathEls = arci.pathEls;\r
-                       // Skip the pathElse check, since we are creatign from another (presumably valid) arci.\r
-               }\r
-               \r
-               public AuthRefConfigInfo(String displayName, String schema, String fullPath, String[] pathEls) {\r
-                       this.displayName = displayName;\r
-                       this.schema = schema;\r
-                       this.fullPath = fullPath;\r
-                       this.pathEls = pathEls;\r
-                       checkPathEls();\r
-               }\r
-\r
-               // Split a config value string like "intakes_common:collector", or\r
-               // "collectionobjects_common:contentPeoples|contentPeople"\r
-               // "collectionobjects_common:assocEventGroupList/*/assocEventPlace"\r
-               // If has a pipe ('|') second part is a displayLabel, and first is path\r
-               // Otherwise, entry is a path, and can use the last pathElement as displayName\r
-               // Should be schema qualified.\r
-               public AuthRefConfigInfo(String configString) {\r
-               String[] pair = configString.split("\\|", 2);\r
-               String[] pathEls;\r
-               String displayName, fullPath;\r
-               if(pair.length == 1) {\r
-                       // no label specifier, so we'll defer getting label\r
-                       fullPath = pair[0];\r
-                       pathEls = pair[0].split("/");\r
-                       displayName = pathEls[pathEls.length-1];\r
-               } else {\r
-                       fullPath = pair[0];\r
-                       pathEls = pair[0].split("/");\r
-                       displayName = pair[1];\r
-               }\r
-               String[] schemaSplit = pathEls[0].split(":",2);\r
-               String schema; \r
-               if(schemaSplit.length==1) {     // schema not specified\r
-                       schema = null;\r
-               } else {\r
-                       schema = schemaSplit[0];\r
-                       if(pair.length == 1 && pathEls.length == 1) {   // simplest case of field in top level schema, no labelll\r
-                               displayName = schemaSplit[1];   // Have to fix up displayName to have no schema\r
-                       }\r
-               }\r
-                       this.displayName = displayName;\r
-                       this.schema = schema;\r
-                       this.fullPath = fullPath;\r
-                       this.pathEls = pathEls;\r
-                       checkPathEls();\r
-               }\r
-               \r
-               protected void checkPathEls() {\r
-               int len = pathEls.length;\r
-               if(len<1)\r
-                       throw new InternalError("Bad values in authRef info - caller screwed up:"+fullPath);\r
-               // Handle case of them putting a leading slash on the path\r
-               if(len>1 && pathEls[0].endsWith(":")) {\r
-                       len--;\r
-                       String[] newArray = new String[len];\r
-                       newArray[0] = pathEls[0]+pathEls[1];\r
-                       if(len>=2) {\r
-                               System.arraycopy(pathEls, 2, newArray, 1, len-1);\r
-                       }\r
-                       pathEls = newArray;\r
-               }\r
-               }\r
-       }\r
-\r
-       public static class AuthRefInfo extends AuthRefConfigInfo {\r
-               public Property getProperty() {\r
-                       return property;\r
-               }\r
-               public void setProperty(Property property) {\r
-                       this.property = property;\r
-               }\r
-               Property property;\r
-               public AuthRefInfo(String displayName, String schema, String fullPath, String[] pathEls, Property prop) {\r
-                       super(displayName, schema, fullPath, pathEls);\r
-                       this.property = prop;\r
-               }\r
-               public AuthRefInfo(AuthRefConfigInfo arci, Property prop) {\r
-                       super(arci);\r
-                       this.property = prop;\r
-               }\r
-       }\r
+    public static class AuthRefConfigInfo {\r
+\r
+        public String getQualifiedDisplayName() {\r
+            return (Tools.isBlank(schema))\r
+                    ? displayName : DocumentUtils.appendSchemaName(schema, displayName);\r
+        }\r
+\r
+        public String getDisplayName() {\r
+            return displayName;\r
+        }\r
+\r
+        public void setDisplayName(String displayName) {\r
+            this.displayName = displayName;\r
+        }\r
+        String displayName;\r
+        String schema;\r
+\r
+        public String getSchema() {\r
+            return schema;\r
+        }\r
+\r
+        public void setSchema(String schema) {\r
+            this.schema = schema;\r
+        }\r
+\r
+        public String getFullPath() {\r
+            return fullPath;\r
+        }\r
+\r
+        public void setFullPath(String fullPath) {\r
+            this.fullPath = fullPath;\r
+        }\r
+        String fullPath;\r
+        protected String[] pathEls;\r
+\r
+        public AuthRefConfigInfo(AuthRefConfigInfo arci) {\r
+            this.displayName = arci.displayName;\r
+            this.schema = arci.schema;\r
+            this.fullPath = arci.fullPath;\r
+            this.pathEls = arci.pathEls;\r
+            // Skip the pathElse check, since we are creatign from another (presumably valid) arci.\r
+        }\r
+\r
+        public AuthRefConfigInfo(String displayName, String schema, String fullPath, String[] pathEls) {\r
+            this.displayName = displayName;\r
+            this.schema = schema;\r
+            this.fullPath = fullPath;\r
+            this.pathEls = pathEls;\r
+            checkPathEls();\r
+        }\r
+\r
+        // Split a config value string like "intakes_common:collector", or\r
+        // "collectionobjects_common:contentPeoples|contentPeople"\r
+        // "collectionobjects_common:assocEventGroupList/*/assocEventPlace"\r
+        // If has a pipe ('|') second part is a displayLabel, and first is path\r
+        // Otherwise, entry is a path, and can use the last pathElement as displayName\r
+        // Should be schema qualified.\r
+        public AuthRefConfigInfo(String configString) {\r
+            String[] pair = configString.split("\\|", 2);\r
+            String[] pathEls;\r
+            String displayName, fullPath;\r
+            if (pair.length == 1) {\r
+                // no label specifier, so we'll defer getting label\r
+                fullPath = pair[0];\r
+                pathEls = pair[0].split("/");\r
+                displayName = pathEls[pathEls.length - 1];\r
+            } else {\r
+                fullPath = pair[0];\r
+                pathEls = pair[0].split("/");\r
+                displayName = pair[1];\r
+            }\r
+            String[] schemaSplit = pathEls[0].split(":", 2);\r
+            String schema;\r
+            if (schemaSplit.length == 1) {    // schema not specified\r
+                schema = null;\r
+            } else {\r
+                schema = schemaSplit[0];\r
+                if (pair.length == 1 && pathEls.length == 1) {    // simplest case of field in top level schema, no labelll\r
+                    displayName = schemaSplit[1];    // Have to fix up displayName to have no schema\r
+                }\r
+            }\r
+            this.displayName = displayName;\r
+            this.schema = schema;\r
+            this.fullPath = fullPath;\r
+            this.pathEls = pathEls;\r
+            checkPathEls();\r
+        }\r
+\r
+        protected void checkPathEls() {\r
+            int len = pathEls.length;\r
+            if (len < 1) {\r
+                throw new InternalError("Bad values in authRef info - caller screwed up:" + fullPath);\r
+            }\r
+            // Handle case of them putting a leading slash on the path\r
+            if (len > 1 && pathEls[0].endsWith(":")) {\r
+                len--;\r
+                String[] newArray = new String[len];\r
+                newArray[0] = pathEls[0] + pathEls[1];\r
+                if (len >= 2) {\r
+                    System.arraycopy(pathEls, 2, newArray, 1, len - 1);\r
+                }\r
+                pathEls = newArray;\r
+            }\r
+        }\r
+    }\r
+\r
+    public static class AuthRefInfo extends AuthRefConfigInfo {\r
+\r
+        public Property getProperty() {\r
+            return property;\r
+        }\r
+\r
+        public void setProperty(Property property) {\r
+            this.property = property;\r
+        }\r
+        Property property;\r
+\r
+        public AuthRefInfo(String displayName, String schema, String fullPath, String[] pathEls, Property prop) {\r
+            super(displayName, schema, fullPath, pathEls);\r
+            this.property = prop;\r
+        }\r
 \r
+        public AuthRefInfo(AuthRefConfigInfo arci, Property prop) {\r
+            super(arci);\r
+            this.property = prop;\r
+        }\r
+    }\r
     private static final Logger logger = LoggerFactory.getLogger(RefNameServiceUtils.class);\r
-    \r
     private static ArrayList<String> refNameServiceTypes = null;\r
-    \r
+\r
     public static List<AuthRefConfigInfo> getConfiguredAuthorityRefs(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx) {\r
-       List<String> authRefFields =\r
+        List<String> authRefFields =\r
                 ((AbstractServiceContextImpl) ctx).getAllPartsPropertyValues(\r
                 ServiceBindingUtils.AUTH_REF_PROP, ServiceBindingUtils.QUALIFIED_PROP_NAMES);\r
-       ArrayList<AuthRefConfigInfo> authRefsInfo = new ArrayList<AuthRefConfigInfo>(authRefFields.size()); \r
-       for(String spec:authRefFields) {\r
-               AuthRefConfigInfo arci = new AuthRefConfigInfo(spec);\r
-               authRefsInfo.add(arci);\r
-       }\r
-       return authRefsInfo;\r
+        ArrayList<AuthRefConfigInfo> authRefsInfo = new ArrayList<AuthRefConfigInfo>(authRefFields.size());\r
+        for (String spec : authRefFields) {\r
+            AuthRefConfigInfo arci = new AuthRefConfigInfo(spec);\r
+            authRefsInfo.add(arci);\r
+        }\r
+        return authRefsInfo;\r
     }\r
 \r
     public static AuthorityRefDocList getAuthorityRefDocs(\r
-               RepositoryInstance repoSession,\r
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
+            RepositoryInstance repoSession,\r
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
             RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient,\r
             List<String> serviceTypes,\r
             String refName,\r
             String refPropName,\r
             DocumentFilter filter, boolean computeTotal)\r
-                       throws DocumentException, DocumentNotFoundException {\r
-       AuthorityRefDocList wrapperList = new AuthorityRefDocList();\r
+            throws DocumentException, DocumentNotFoundException {\r
+        AuthorityRefDocList wrapperList = new AuthorityRefDocList();\r
         AbstractCommonList commonList = (AbstractCommonList) wrapperList;\r
         int pageNum = filter.getStartPage();\r
-        int pageSize = filter.getPageSize(); \r
+        int pageSize = filter.getPageSize();\r
         commonList.setPageNum(pageNum);\r
         commonList.setPageSize(pageSize);\r
         List<AuthorityRefDocList.AuthorityRefDocItem> list =\r
                 wrapperList.getAuthorityRefDocItem();\r
-        \r
+\r
         Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
         Map<String, List<AuthRefConfigInfo>> authRefFieldsByService = new HashMap<String, List<AuthRefConfigInfo>>();\r
 \r
-        RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl)repoClient;\r
-       try {\r
-               DocumentModelList docList = findAuthorityRefDocs(ctx, repoClient, repoSession,\r
-                               serviceTypes, refName, refPropName, queriedServiceBindings, authRefFieldsByService,\r
-                               filter.getWhereClause(), 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
-               // set the fieldsReturned list. Even though this is a fixed schema, app layer treats\r
-               // this like other abstract common lists\r
-               /*\r
-                       <xs:element name="docType"         type="xs:string" minOccurs="1" />\r
-                       <xs:element name="docId"           type="xs:string" minOccurs="1" />\r
-                       <xs:element name="docNumber"       type="xs:string" minOccurs="0" />\r
-                       <xs:element name="docName"         type="xs:string" minOccurs="0" />\r
-                       <xs:element name="sourceField"     type="xs:string" minOccurs="1" />\r
-                       <xs:element name="uri"             type="xs:anyURI" minOccurs="1" />\r
-                       <xs:element name="updatedAt"       type="xs:string" minOccurs="1" />\r
-                       <xs:element name="workflowState"   type="xs:string" minOccurs="1" />\r
-                       */\r
-               String fieldList = "docType|docId|docNumber|docName|sourceField|uri|updatedAt|workflowState";\r
-               commonList.setFieldsReturned(fieldList);\r
-               \r
-               int nRefsFound = processRefObjsDocList(docList, refName, queriedServiceBindings, authRefFieldsByService, // the actual list size needs to be updated to the size of "list"\r
-                                                               list, null);\r
-               if(logger.isDebugEnabled() && (nRefsFound < docList.size())) {\r
-                       logger.debug("Internal curiosity: got fewer matches of refs than # docs matched..."); // We found a ref to ourself and have excluded it.\r
-               }\r
-       } catch (Exception e) {\r
-                       logger.error("Could not retrieve the Nuxeo repository", e);\r
-                       wrapperList = null;\r
-       }\r
-              \r
-       return wrapperList;\r
+        RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl) repoClient;\r
+        try {\r
+            DocumentModelList docList = findAuthorityRefDocs(ctx, repoClient, repoSession,\r
+                    serviceTypes, refName, refPropName, queriedServiceBindings, authRefFieldsByService,\r
+                    filter.getWhereClause(), null, 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
+            // set the fieldsReturned list. Even though this is a fixed schema, app layer treats\r
+            // this like other abstract common lists\r
+            /*\r
+             * <xs:element name="docType" type="xs:string" minOccurs="1" />\r
+             * <xs:element name="docId" type="xs:string" minOccurs="1" />\r
+             * <xs:element name="docNumber" type="xs:string" minOccurs="0" />\r
+             * <xs:element name="docName" type="xs:string" minOccurs="0" />\r
+             * <xs:element name="sourceField" type="xs:string" minOccurs="1" />\r
+             * <xs:element name="uri" type="xs:anyURI" minOccurs="1" />\r
+             * <xs:element name="updatedAt" type="xs:string" minOccurs="1" />\r
+             * <xs:element name="workflowState" type="xs:string" minOccurs="1"\r
+             * />\r
+             */\r
+            String fieldList = "docType|docId|docNumber|docName|sourceField|uri|updatedAt|workflowState";\r
+            commonList.setFieldsReturned(fieldList);\r
+\r
+            int nRefsFound = processRefObjsDocList(docList, refName, queriedServiceBindings, authRefFieldsByService, // the actual list size needs to be updated to the size of "list"\r
+                    list, null);\r
+            if (logger.isDebugEnabled() && (nRefsFound < docList.size())) {\r
+                logger.debug("Internal curiosity: got fewer matches of refs than # docs matched..."); // We found a ref to ourself and have excluded it.\r
+            }\r
+        } catch (Exception e) {\r
+            logger.error("Could not retrieve the Nuxeo repository", e);\r
+            wrapperList = null;\r
+        }\r
+\r
+        return wrapperList;\r
     }\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
+        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
     // Seems like a good value - no real data to set this well.\r
-    private static final int N_OBJS_TO_UPDATE_PER_LOOP = 100;\r
-    \r
+    // private static final int N_OBJS_TO_UPDATE_PER_LOOP = 100;\r
+    // FIXME: This value is set to 3 during debugging; needs to be set higher during production - ADR 2012-07-10\r
+    private static final int N_OBJS_TO_UPDATE_PER_LOOP = 3;\r
+\r
     public static int updateAuthorityRefDocs(\r
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
             RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient,\r
             RepositoryInstance repoSession,\r
             String oldRefName,\r
             String newRefName,\r
-            String refPropName ) throws Exception {\r
+            String refPropName) throws Exception {\r
         Map<String, ServiceBindingType> queriedServiceBindings = new HashMap<String, ServiceBindingType>();\r
         Map<String, List<AuthRefConfigInfo>> authRefFieldsByService = new HashMap<String, List<AuthRefConfigInfo>>();\r
+\r
+        int docsScanned = 0;\r
         int nRefsFound = 0;\r
-        if(!(repoClient instanceof RepositoryJavaClientImpl)) {\r
-               throw new InternalError("updateAuthorityRefDocs() called with unknown repoClient type!");\r
-        }\r
-        try { // REM - How can we deal with transaction and timeout issues hear.\r
-               final int pageSize = N_OBJS_TO_UPDATE_PER_LOOP; // Set a limit of num of objects -something like 1000K objects and also add a log Warning after some threshold\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. Slightly inefficient, but more\r
-                       // reliable (stateless).\r
-                       DocumentModelList docList = findAuthorityRefDocs(ctx, repoClient, repoSession, //is there an orderBy clause?  set the orderby clause to something non-transient like createAt\r
-                                       getRefNameServiceTypes(), oldRefName, refPropName,\r
-                                       queriedServiceBindings, authRefFieldsByService, null, pageSize, 0, false /*don't compute total*/); //loop through the pages until we're finished -i.e., don't just keep getting the first page\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, repoSession, docList, true);\r
-                               nRefsFound += nRefsFoundThisPage;\r
-                       }\r
-                       pageNumProcessed++;\r
-                       if(docList.size()<pageSize) {\r
-                               logger.debug("updateAuthorityRefDocs: assuming no more results, as nResults < pageSize");\r
-                               break;\r
-                       }\r
-               }\r
+        int currentPage = 0;\r
+        int docsInCurrentPage = 0;\r
+        final String WHERE_CLAUSE_ADDITIONS_VALUE = null;\r
+        final String ORDER_BY_VALUE = "collectionspace_core:createdAt";\r
+\r
+        if (!(repoClient instanceof RepositoryJavaClientImpl)) {\r
+            throw new InternalError("updateAuthorityRefDocs() called with unknown repoClient type!");\r
+        }\r
+        try { // REM - How can we deal with transaction and timeout issues here.\r
+            final int pageSize = N_OBJS_TO_UPDATE_PER_LOOP;\r
+            DocumentModelList docList;\r
+            boolean morePages = true;\r
+            while (morePages) {\r
+                \r
+                docList = findAuthorityRefDocs(ctx, repoClient, repoSession,\r
+                        getRefNameServiceTypes(), oldRefName, refPropName,\r
+                        queriedServiceBindings, authRefFieldsByService, WHERE_CLAUSE_ADDITIONS_VALUE, ORDER_BY_VALUE, pageSize, currentPage, false);\r
+                \r
+                if (docList == null) {\r
+                    logger.debug("updateAuthorityRefDocs: no documents could be found that referenced the old refName");\r
+                    break;\r
+                }\r
+                docsInCurrentPage = docList.size();\r
+                logger.debug("updateAuthorityRefDocs: current page=" + currentPage + " documents included in page=" + docsInCurrentPage);\r
+                if (docsInCurrentPage == 0) {\r
+                    logger.debug("updateAuthorityRefDocs: no more documents requiring refName updates could be found");\r
+                    break;\r
+                }\r
+                if (docsInCurrentPage < pageSize) {\r
+                    logger.debug("updateAuthorityRefDocs: assuming no more documents requiring refName updates will be found, as docsInCurrentPage < pageSize");\r
+                    morePages = false;\r
+                }\r
+\r
+                int nRefsFoundThisPage = processRefObjsDocList(docList, oldRefName, queriedServiceBindings, authRefFieldsByService,\r
+                        null, newRefName);\r
+                if (nRefsFoundThisPage > 0) {\r
+                    ((RepositoryJavaClientImpl) repoClient).saveDocListWithoutHandlerProcessing(ctx, repoSession, docList, true);\r
+                    nRefsFound += nRefsFoundThisPage;\r
+                }\r
+                \r
+                // FIXME: Per REM, set a limit of num objects - something like\r
+                // 1000K objects - and also add a log Warning after some threshold\r
+                docsScanned += docsInCurrentPage;\r
+                if (morePages) {\r
+                    currentPage++;\r
+                }\r
+\r
+            }\r
         } catch (Exception e) {\r
-               logger.error("Internal error updating the AuthorityRefDocs: " + e.getLocalizedMessage());\r
-               logger.debug(Tools.errorToString(e, true));\r
-               throw e;\r
+            logger.error("Internal error updating the AuthorityRefDocs: " + e.getLocalizedMessage());\r
+            logger.debug(Tools.errorToString(e, true));\r
+            throw e;\r
         }\r
-               logger.debug("updateAuthorityRefDocs replaced a total of: "+nRefsFound);\r
+        logger.debug("updateAuthorityRefDocs replaced a total of " + nRefsFound + " authority references, within as many as " + docsScanned + " scanned document(s)");\r
         return nRefsFound;\r
     }\r
-    \r
+\r
     private static DocumentModelList findAuthorityRefDocs(\r
-               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
             RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient,\r
-            RepositoryInstance repoSession,\r
-            List<String> serviceTypes,\r
+            RepositoryInstance repoSession, List<String> serviceTypes,\r
             String refName,\r
             String refPropName,\r
             Map<String, ServiceBindingType> queriedServiceBindings,\r
             Map<String, List<AuthRefConfigInfo>> authRefFieldsByService,\r
             String whereClauseAdditions,\r
-            int pageSize, int pageNum, boolean computeTotal) throws DocumentException, DocumentNotFoundException {\r
+            String orderByClause,\r
+            int pageSize,\r
+            int pageNum,\r
+            boolean computeTotal) throws DocumentException, DocumentNotFoundException {\r
 \r
         // Get the service bindings for this tenant\r
         TenantBindingConfigReaderImpl tReader =\r
@@ -353,58 +384,57 @@ public class RefNameServiceUtils {
         // 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
+            logger.error("RefNameServiceUtils.getAuthorityRefDocs: No services bindings found, cannot proceed!");\r
             return null;\r
         }\r
         // Filter the list for current user rights\r
         servicebindings = SecurityUtils.getReadableServiceBindingsForCurrentUser(servicebindings);\r
-        \r
+\r
         ArrayList<String> docTypes = new ArrayList<String>();\r
-        \r
-        String query = computeWhereClauseForAuthorityRefDocs(refName, refPropName, docTypes, servicebindings, \r
-                                                                                               queriedServiceBindings, authRefFieldsByService );\r
+\r
+        String query = computeWhereClauseForAuthorityRefDocs(refName, refPropName, docTypes, servicebindings,\r
+                queriedServiceBindings, authRefFieldsByService);\r
         if (query == null) { // found no authRef fields - nothing to query\r
             return null;\r
         }\r
         // Additional qualifications, like workflow state\r
-        if(whereClauseAdditions!=null) {\r
-               query += " AND " + whereClauseAdditions;\r
-        }\r
+        if (Tools.notBlank(whereClauseAdditions)) {\r
+            query += " AND " + whereClauseAdditions;\r
+        }        \r
         // Now we have to issue the search\r
-        RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl)repoClient;\r
+        RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl) repoClient;\r
         DocumentWrapper<DocumentModelList> docListWrapper = nuxeoRepoClient.findDocs(ctx, repoSession,\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
         return docList;\r
     }\r
-    \r
     private static final boolean READY_FOR_COMPLEX_QUERY = true;\r
-    \r
+\r
     private static String computeWhereClauseForAuthorityRefDocs(\r
-               String refName,\r
-               String refPropName,\r
-               ArrayList<String> docTypes,\r
-               List<ServiceBindingType> servicebindings,\r
-               Map<String, ServiceBindingType> queriedServiceBindings,\r
-               Map<String, List<AuthRefConfigInfo>> authRefFieldsByService ) {\r
+            String refName,\r
+            String refPropName,\r
+            ArrayList<String> docTypes,\r
+            List<ServiceBindingType> servicebindings,\r
+            Map<String, ServiceBindingType> queriedServiceBindings,\r
+            Map<String, List<AuthRefConfigInfo>> authRefFieldsByService) {\r
 \r
         boolean fFirst = true;\r
         List<String> authRefFieldPaths;\r
         for (ServiceBindingType sb : servicebindings) {\r
-               // Gets the property names for each part, qualified with the part label (which\r
-               // is also the table name, the way that the repository works).\r
+            // Gets the property names for each part, qualified with the part label (which\r
+            // is also the table name, the way that the repository works).\r
             authRefFieldPaths =\r
                     ServiceBindingUtils.getAllPartsPropertyValues(sb,\r
-                               refPropName, ServiceBindingUtils.QUALIFIED_PROP_NAMES);\r
+                    refPropName, ServiceBindingUtils.QUALIFIED_PROP_NAMES);\r
             if (authRefFieldPaths.isEmpty()) {\r
                 continue;\r
             }\r
             ArrayList<AuthRefConfigInfo> authRefsInfo = new ArrayList<AuthRefConfigInfo>();\r
-               for(String spec:authRefFieldPaths) {\r
-                       AuthRefConfigInfo arci = new AuthRefConfigInfo(spec);\r
-                       authRefsInfo.add(arci);\r
-               }\r
+            for (String spec : authRefFieldPaths) {\r
+                AuthRefConfigInfo arci = new AuthRefConfigInfo(spec);\r
+                authRefsInfo.add(arci);\r
+            }\r
 \r
             String docType = sb.getObject().getName();\r
             queriedServiceBindings.put(docType, sb);\r
@@ -420,37 +450,37 @@ public class RefNameServiceUtils {
         // Note that this will also match the Item itself, but that will get filtered out when\r
         // we compute actual matches.\r
         AuthorityTermInfo authTermInfo = RefNameUtils.parseAuthorityTermInfo(refName);\r
-               \r
-        String keywords = RefNameUtils.URN_PREFIX \r
-                                       + " AND " + (authTermInfo.inAuthority.name!=null?\r
-                                                       authTermInfo.inAuthority.name:authTermInfo.inAuthority.csid)\r
-                                       + " AND " + (authTermInfo.name!=null?\r
-                                                       authTermInfo.name:authTermInfo.csid);\r
-        \r
+\r
+        String keywords = RefNameUtils.URN_PREFIX\r
+                + " AND " + (authTermInfo.inAuthority.name != null\r
+                ? authTermInfo.inAuthority.name : authTermInfo.inAuthority.csid)\r
+                + " AND " + (authTermInfo.name != null\r
+                ? authTermInfo.name : authTermInfo.csid);\r
+\r
         String whereClauseStr = QueryManager.createWhereClauseFromKeywords(keywords);\r
-        \r
+\r
         if (logger.isTraceEnabled()) {\r
-               logger.trace("The 'where' clause to find refObjs is: ", whereClauseStr);\r
+            logger.trace("The 'where' clause to find refObjs is: ", whereClauseStr);\r
         }\r
-        \r
-        return whereClauseStr; \r
+\r
+        return whereClauseStr;\r
     }\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
-     *   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
+     * Runs through the list of found docs, processing them. If list is\r
+     * non-null, then processing means gather the info for items. If list is\r
+     * null, and newRefName is non-null, then processing means replacing and\r
+     * updating. If processing/updating, this must be called in teh context of\r
+     * an open session, and caller must release Session after calling this.\r
+     *\r
      */\r
     private static int processRefObjsDocList(\r
-               DocumentModelList docList,\r
-               String refName,\r
-               Map<String, ServiceBindingType> queriedServiceBindings,\r
-               Map<String, List<AuthRefConfigInfo>> authRefFieldsByService,\r
-                       List<AuthorityRefDocList.AuthorityRefDocItem> list, \r
-                       String newAuthorityRefName) {\r
+            DocumentModelList docList,\r
+            String refName,\r
+            Map<String, ServiceBindingType> queriedServiceBindings,\r
+            Map<String, List<AuthRefConfigInfo>> authRefFieldsByService,\r
+            List<AuthorityRefDocList.AuthorityRefDocItem> list,\r
+            String newAuthorityRefName) {\r
         Iterator<DocumentModel> iter = docList.iterator();\r
         int nRefsFoundTotal = 0;\r
         while (iter.hasNext()) {\r
@@ -465,25 +495,25 @@ public class RefNameServiceUtils {
                         "getAuthorityRefDocs: No Service Binding for docType: " + docType);\r
             }\r
             String serviceContextPath = "/" + sb.getName().toLowerCase() + "/";\r
-            \r
-            if(list == null) { // no list - should be update refName case.\r
-               if(newAuthorityRefName==null) {\r
-                       throw new InternalError("processRefObjsDocList() called with neither an itemList nor a new RefName!");\r
-                       }\r
-               ilistItem = null;\r
-            } else {   // Have a list - refObjs case\r
-               if(newAuthorityRefName!=null) {\r
-                       throw new InternalError("processRefObjsDocList() called with both an itemList and a new RefName!");\r
-               }\r
-               ilistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
+\r
+            if (list == null) { // no list - should be update refName case.\r
+                if (newAuthorityRefName == null) {\r
+                    throw new InternalError("processRefObjsDocList() called with neither an itemList nor a new RefName!");\r
+                }\r
+                ilistItem = null;\r
+            } else {    // Have a list - refObjs case\r
+                if (newAuthorityRefName != null) {\r
+                    throw new InternalError("processRefObjsDocList() called with both an itemList and a new RefName!");\r
+                }\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
                 try {\r
                     ilistItem.setWorkflowState(docModel.getCurrentLifeCycleState());\r
-                       ilistItem.setUpdatedAt(DocHandlerBase.getUpdatedAtAsString(docModel));\r
-                } catch(Exception e) {\r
-                       logger.error("Error getting core values for doc ["+csid+"]: "+e.getLocalizedMessage());\r
+                    ilistItem.setUpdatedAt(DocHandlerBase.getUpdatedAtAsString(docModel));\r
+                } catch (Exception e) {\r
+                    logger.error("Error getting core values for doc [" + csid + "]: " + e.getLocalizedMessage());\r
                 }\r
                 // The id and URI are the same on all doctypes\r
                 ilistItem.setDocType(docType);\r
@@ -503,25 +533,24 @@ public class RefNameServiceUtils {
             //String authRefDescendantField = "";\r
             //String sourceField = "";\r
             int nRefsFoundInDoc = 0;\r
-            \r
-            ArrayList<RefNameServiceUtils.AuthRefInfo> foundProps \r
-                                               = new ArrayList<RefNameServiceUtils.AuthRefInfo>();\r
+\r
+            ArrayList<RefNameServiceUtils.AuthRefInfo> foundProps = new ArrayList<RefNameServiceUtils.AuthRefInfo>();\r
             try {\r
-                   findAuthRefPropertiesInDoc(docModel, matchingAuthRefFields, refName, foundProps);\r
-                   for(RefNameServiceUtils.AuthRefInfo ari:foundProps) {\r
-                               if(ilistItem != null) {\r
-                               if(nRefsFoundInDoc == 0) {      // First one?\r
-                                       ilistItem.setSourceField(ari.getQualifiedDisplayName());\r
-                               } else {        // duplicates from one object\r
-                                       ilistItem = cloneAuthRefDocItem(ilistItem, ari.getQualifiedDisplayName());\r
-                               }\r
-                                       list.add(ilistItem);\r
-                               } else {        // update refName case\r
-                                       Property propToUpdate = ari.getProperty();\r
-                                       propToUpdate.setValue(newAuthorityRefName);\r
-                               }\r
-                               nRefsFoundInDoc++;\r
-                   }\r
+                findAuthRefPropertiesInDoc(docModel, matchingAuthRefFields, refName, foundProps);\r
+                for (RefNameServiceUtils.AuthRefInfo ari : foundProps) {\r
+                    if (ilistItem != null) {\r
+                        if (nRefsFoundInDoc == 0) {    // First one?\r
+                            ilistItem.setSourceField(ari.getQualifiedDisplayName());\r
+                        } else {    // duplicates from one object\r
+                            ilistItem = cloneAuthRefDocItem(ilistItem, ari.getQualifiedDisplayName());\r
+                        }\r
+                        list.add(ilistItem);\r
+                    } else {    // update refName case\r
+                        Property propToUpdate = ari.getProperty();\r
+                        propToUpdate.setValue(newAuthorityRefName);\r
+                    }\r
+                    nRefsFoundInDoc++;\r
+                }\r
             } catch (ClientException ce) {\r
                 throw new RuntimeException(\r
                         "getAuthorityRefDocs: Problem fetching values from repo: " + ce.getLocalizedMessage());\r
@@ -537,178 +566,155 @@ public class RefNameServiceUtils {
         }\r
         return nRefsFoundTotal;\r
     }\r
-    \r
+\r
     private static AuthorityRefDocList.AuthorityRefDocItem cloneAuthRefDocItem(\r
-               AuthorityRefDocList.AuthorityRefDocItem ilistItem, String sourceField) {\r
-       AuthorityRefDocList.AuthorityRefDocItem newlistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
-       newlistItem.setDocId(ilistItem.getDocId());\r
-       newlistItem.setDocName(ilistItem.getDocName());\r
-       newlistItem.setDocNumber(ilistItem.getDocNumber());\r
-       newlistItem.setDocType(ilistItem.getDocType());\r
-       newlistItem.setUri(ilistItem.getUri());\r
-       newlistItem.setSourceField(sourceField);\r
-       return newlistItem;\r
+            AuthorityRefDocList.AuthorityRefDocItem ilistItem, String sourceField) {\r
+        AuthorityRefDocList.AuthorityRefDocItem newlistItem = new AuthorityRefDocList.AuthorityRefDocItem();\r
+        newlistItem.setDocId(ilistItem.getDocId());\r
+        newlistItem.setDocName(ilistItem.getDocName());\r
+        newlistItem.setDocNumber(ilistItem.getDocNumber());\r
+        newlistItem.setDocType(ilistItem.getDocType());\r
+        newlistItem.setUri(ilistItem.getUri());\r
+        newlistItem.setSourceField(sourceField);\r
+        return newlistItem;\r
     }\r
-    \r
-    public static List<AuthRefInfo> findAuthRefPropertiesInDoc( \r
-               DocumentModel docModel, \r
-               List<AuthRefConfigInfo> authRefFieldInfo,\r
-               String refNameToMatch,\r
-               List<AuthRefInfo> foundProps\r
-               ) {\r
-       // Assume that authRefFieldInfo is keyed by the field name (possibly mapped for UI)\r
-       // and the values are elPaths to the field, where intervening group structures in\r
-       // lists of complex structures are replaced with "*". Thus, valid paths include\r
-       // the following (note that the ServiceBindingUtils prepend schema names to configured values):\r
-       // "schemaname:fieldname"\r
-       // "schemaname:scalarlistname"\r
-       // "schemaname:complexfieldname/fieldname"\r
-       // "schemaname:complexlistname/*/fieldname"\r
-       // "schemaname:complexlistname/*/scalarlistname"\r
-       // "schemaname:complexlistname/*/complexfieldname/fieldname"\r
-       // "schemaname:complexlistname/*/complexlistname/*/fieldname"\r
-       // etc.\r
+\r
+    public static List<AuthRefInfo> findAuthRefPropertiesInDoc(\r
+            DocumentModel docModel,\r
+            List<AuthRefConfigInfo> authRefFieldInfo,\r
+            String refNameToMatch,\r
+            List<AuthRefInfo> foundProps) {\r
+        // Assume that authRefFieldInfo is keyed by the field name (possibly mapped for UI)\r
+        // and the values are elPaths to the field, where intervening group structures in\r
+        // lists of complex structures are replaced with "*". Thus, valid paths include\r
+        // the following (note that the ServiceBindingUtils prepend schema names to configured values):\r
+        // "schemaname:fieldname"\r
+        // "schemaname:scalarlistname"\r
+        // "schemaname:complexfieldname/fieldname"\r
+        // "schemaname:complexlistname/*/fieldname"\r
+        // "schemaname:complexlistname/*/scalarlistname"\r
+        // "schemaname:complexlistname/*/complexfieldname/fieldname"\r
+        // "schemaname:complexlistname/*/complexlistname/*/fieldname"\r
+        // etc.\r
         for (AuthRefConfigInfo arci : authRefFieldInfo) {\r
             try {\r
-               // Get first property and work down as needed.\r
-                       Property prop = docModel.getProperty(arci.pathEls[0]);\r
-                       findAuthRefPropertiesInProperty(foundProps, prop, arci, 0, refNameToMatch);\r
-            } catch(Exception e) {\r
-               logger.error("Problem fetching property: "+arci.pathEls[0]);\r
+                // Get first property and work down as needed.\r
+                Property prop = docModel.getProperty(arci.pathEls[0]);\r
+                findAuthRefPropertiesInProperty(foundProps, prop, arci, 0, refNameToMatch);\r
+            } catch (Exception e) {\r
+                logger.error("Problem fetching property: " + arci.pathEls[0]);\r
             }\r
         }\r
         return foundProps;\r
     }\r
 \r
     public static List<AuthRefInfo> findAuthRefPropertiesInProperty(\r
-               List<AuthRefInfo> foundProps,\r
-               Property prop, \r
-               AuthRefConfigInfo arci,\r
-               int pathStartIndex,             // Supports recursion and we work down the path\r
-               String refNameToMatch\r
-               ) {\r
-       if (pathStartIndex >= arci.pathEls.length) {\r
-               throw new ArrayIndexOutOfBoundsException("Index = "+pathStartIndex+" for path: "\r
-                                                                                               +arci.pathEls.toString());\r
-       }\r
-               AuthRefInfo ari = null;\r
-               if (prop == null) {\r
-                       return foundProps;\r
-               }\r
-               \r
-               if (prop instanceof StringProperty) {   // scalar string\r
-                       addARIifMatches(refNameToMatch, arci, prop, foundProps);\r
-               } else if(prop instanceof List) {\r
-                       List<Property> propList = (List<Property>)prop;\r
-                       // run through list. Must either be list of Strings, or Complex\r
-                       for (Property listItemProp : propList) {\r
-                               if(listItemProp instanceof StringProperty) {\r
-                                       if(arci.pathEls.length-pathStartIndex != 1) {\r
-                                               logger.error("Configuration for authRefs does not match schema structure: "\r
-                                                               +arci.pathEls.toString());\r
-                                               break;\r
-                                       } else {\r
-                                               addARIifMatches(refNameToMatch, arci, listItemProp, foundProps);\r
-                                       }\r
-                               } else if(listItemProp.isComplex()) {   \r
-                                       // Just recurse to handle this. Note that since this is a list of complex, \r
-                                       // which should look like listName/*/... we add 2 to the path start index \r
-                                       findAuthRefPropertiesInProperty(foundProps, listItemProp, arci,\r
-                                                       pathStartIndex+2, refNameToMatch);\r
-                               } else {\r
-                                       logger.error("Configuration for authRefs does not match schema structure: "\r
-                                                       +arci.pathEls.toString());\r
-                                       break;\r
-                               }\r
-                       }\r
-               } else if(prop.isComplex()) {\r
-                       String localPropName = arci.pathEls[pathStartIndex];\r
-                       try {\r
-                               Property localProp = prop.get(localPropName);\r
-                               // Now just recurse, pushing down the path 1 step\r
-                               findAuthRefPropertiesInProperty(foundProps, localProp, arci, \r
-                                                                                               pathStartIndex, refNameToMatch);\r
-                       } catch(PropertyNotFoundException pnfe) {\r
-                               logger.error("Could not find property: ["+localPropName+"] in path: "+\r
-                                                               arci.getFullPath());\r
-                               // Fall through - ari will be null and we will continue...\r
-                       }\r
-               } else {\r
-                               logger.error("Configuration for authRefs does not match schema structure: "\r
-                                               +arci.pathEls.toString());\r
-               }\r
-\r
-       if (ari != null) {\r
-               foundProps.add(ari); //FIXME: REM - This is dead code.  'ari' is never touched after being initalized to null.  Why?\r
-       }\r
-       \r
-       return foundProps;\r
+            List<AuthRefInfo> foundProps,\r
+            Property prop,\r
+            AuthRefConfigInfo arci,\r
+            int pathStartIndex, // Supports recursion and we work down the path\r
+            String refNameToMatch) {\r
+        if (pathStartIndex >= arci.pathEls.length) {\r
+            throw new ArrayIndexOutOfBoundsException("Index = " + pathStartIndex + " for path: "\r
+                    + arci.pathEls.toString());\r
+        }\r
+        AuthRefInfo ari = null;\r
+        if (prop == null) {\r
+            return foundProps;\r
+        }\r
+\r
+        if (prop instanceof StringProperty) {    // scalar string\r
+            addARIifMatches(refNameToMatch, arci, prop, foundProps);\r
+        } else if (prop instanceof List) {\r
+            List<Property> propList = (List<Property>) prop;\r
+            // run through list. Must either be list of Strings, or Complex\r
+            for (Property listItemProp : propList) {\r
+                if (listItemProp instanceof StringProperty) {\r
+                    if (arci.pathEls.length - pathStartIndex != 1) {\r
+                        logger.error("Configuration for authRefs does not match schema structure: "\r
+                                + arci.pathEls.toString());\r
+                        break;\r
+                    } else {\r
+                        addARIifMatches(refNameToMatch, arci, listItemProp, foundProps);\r
+                    }\r
+                } else if (listItemProp.isComplex()) {\r
+                    // Just recurse to handle this. Note that since this is a list of complex, \r
+                    // which should look like listName/*/... we add 2 to the path start index \r
+                    findAuthRefPropertiesInProperty(foundProps, listItemProp, arci,\r
+                            pathStartIndex + 2, refNameToMatch);\r
+                } else {\r
+                    logger.error("Configuration for authRefs does not match schema structure: "\r
+                            + arci.pathEls.toString());\r
+                    break;\r
+                }\r
+            }\r
+        } else if (prop.isComplex()) {\r
+            String localPropName = arci.pathEls[pathStartIndex];\r
+            try {\r
+                Property localProp = prop.get(localPropName);\r
+                // Now just recurse, pushing down the path 1 step\r
+                findAuthRefPropertiesInProperty(foundProps, localProp, arci,\r
+                        pathStartIndex, refNameToMatch);\r
+            } catch (PropertyNotFoundException pnfe) {\r
+                logger.error("Could not find property: [" + localPropName + "] in path: "\r
+                        + arci.getFullPath());\r
+                // Fall through - ari will be null and we will continue...\r
+            }\r
+        } else {\r
+            logger.error("Configuration for authRefs does not match schema structure: "\r
+                    + arci.pathEls.toString());\r
+        }\r
+\r
+        if (ari != null) {\r
+            foundProps.add(ari); //FIXME: REM - This is dead code.  'ari' is never touched after being initalized to null.  Why?\r
+        }\r
+\r
+        return foundProps;\r
     }\r
-    \r
+\r
     private static void addARIifMatches(\r
-               String refNameToMatch, \r
-               AuthRefConfigInfo arci, \r
-               Property prop, \r
-               List<AuthRefInfo> foundProps) {\r
-               // Need to either match a passed refName \r
-               // OR have no refName to match but be non-empty\r
-       try {\r
-               String value = (String)prop.getValue();\r
-                       if(((refNameToMatch!=null) && refNameToMatch.equals(value))\r
-                                       || ((refNameToMatch==null) && Tools.notBlank(value))) {\r
-                               // Found a match\r
-                               logger.debug("Found a match on property: "+prop.getPath()+" with value: ["+value+"]");\r
-                               AuthRefInfo ari = new AuthRefInfo(arci, prop);\r
-                               foundProps.add(ari);\r
-                       }\r
-       } catch(PropertyException pe) {\r
-                       logger.debug("PropertyException on: "+prop.getPath()+pe.getLocalizedMessage());\r
-       }\r
+            String refNameToMatch,\r
+            AuthRefConfigInfo arci,\r
+            Property prop,\r
+            List<AuthRefInfo> foundProps) {\r
+        // Need to either match a passed refName \r
+        // OR have no refName to match but be non-empty\r
+        try {\r
+            String value = (String) prop.getValue();\r
+            if (((refNameToMatch != null) && refNameToMatch.equals(value))\r
+                    || ((refNameToMatch == null) && Tools.notBlank(value))) {\r
+                // Found a match\r
+                logger.debug("Found a match on property: " + prop.getPath() + " with value: [" + value + "]");\r
+                AuthRefInfo ari = new AuthRefInfo(arci, prop);\r
+                foundProps.add(ari);\r
+            }\r
+        } catch (PropertyException pe) {\r
+            logger.debug("PropertyException on: " + prop.getPath() + pe.getLocalizedMessage());\r
+        }\r
     }\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
+     * Identifies whether the refName was found in the supplied field. If passed\r
+     * a new RefName, will set that into fields in which the old one was found.\r
      *\r
-     * Only works for:\r
-     * * Scalar fields\r
-     * * Repeatable scalar fields (aka multi-valued fields)\r
+     * Only works for: * Scalar fields * Repeatable scalar fields (aka\r
+     * multi-valued fields)\r
      *\r
-     * Does not work for:\r
-     * * Structured fields (complexTypes)\r
-     * * Repeatable structured fields (repeatable complexTypes)\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
+     * Does not work for: * Structured fields (complexTypes) * Repeatable\r
+     * structured fields (repeatable complexTypes) private static int\r
+     * refNameFoundInField(String oldRefName, Property fieldValue, String\r
+     * newRefName) { int nFound = 0; if (fieldValue instanceof List) {\r
+     * List<Property> fieldValueList = (List) fieldValue; for (Property\r
+     * listItemValue : fieldValueList) { try { if ((listItemValue instanceof\r
+     * StringProperty) &&\r
+     * oldRefName.equalsIgnoreCase((String)listItemValue.getValue())) {\r
+     * nFound++; if(newRefName!=null) { fieldValue.setValue(newRefName); } else\r
+     * { // We cannot quit after the first, if we are replacing values. // If we\r
+     * are just looking (not replacing), finding one is enough. break; } } }\r
+     * catch( PropertyException pe ) {} } } else { try { if ((fieldValue\r
+     * instanceof StringProperty) &&\r
+     * oldRefName.equalsIgnoreCase((String)fieldValue.getValue())) { nFound++;\r
+     * if(newRefName!=null) { fieldValue.setValue(newRefName); } } } catch(\r
+     * PropertyException pe ) {} } return nFound; }\r
      */\r
 }\r
-\r