]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-6935: Adding sync support for both individual authorities and authority terms.
authorRichard Millet <remillet@yahoo.com>
Fri, 8 Apr 2016 05:45:16 +0000 (22:45 -0700)
committerRichard Millet <remillet@yahoo.com>
Fri, 8 Apr 2016 05:45:16 +0000 (22:45 -0700)
27 files changed:
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityDocumentModelHandler.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/nuxeo/AuthorityItemDocumentModelHandler.java
services/citation/service/src/main/java/org/collectionspace/services/citation/nuxeo/CitationDocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/common/NuxeoBasedResource.java
services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
services/common/src/main/java/org/collectionspace/services/common/context/AbstractServiceContextImpl.java
services/common/src/main/java/org/collectionspace/services/common/context/MultipartServiceContextImpl.java
services/common/src/main/java/org/collectionspace/services/common/context/RemoteServiceContextImpl.java
services/common/src/main/java/org/collectionspace/services/common/context/ServiceContext.java
services/common/src/main/java/org/collectionspace/services/common/document/AbstractDocumentHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/common/document/DocumentHandler.java
services/common/src/main/java/org/collectionspace/services/common/storage/StorageClient.java
services/common/src/main/java/org/collectionspace/services/common/storage/jpa/JpaStorageClientImpl.java
services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/NuxeoDocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryClientImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java
services/concept/service/src/main/java/org/collectionspace/services/concept/nuxeo/ConceptDocumentModelHandler.java
services/location/service/src/main/java/org/collectionspace/services/location/nuxeo/LocationDocumentModelHandler.java
services/material/service/src/main/java/org/collectionspace/services/material/nuxeo/MaterialDocumentModelHandler.java
services/organization/service/src/main/java/org/collectionspace/services/organization/nuxeo/OrganizationDocumentModelHandler.java
services/person/service/src/main/java/org/collectionspace/services/person/nuxeo/PersonDocumentModelHandler.java
services/place/service/src/main/java/org/collectionspace/services/place/nuxeo/PlaceDocumentModelHandler.java
services/taxonomy/service/src/main/java/org/collectionspace/services/taxonomy/nuxeo/TaxonDocumentModelHandler.java
services/vocabulary/service/src/main/java/org/collectionspace/services/vocabulary/nuxeo/VocabularyItemDocumentModelHandler.java
services/work/service/src/main/java/org/collectionspace/services/work/nuxeo/WorkDocumentModelHandler.java

index 96abf6c08522fa4f546e214ad7d32a8fc1d0b3a2..60547b7880c738ed8bbfc032d0b3fbaab6ebe2ff 100644 (file)
@@ -83,10 +83,9 @@ import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentFilter;
 import org.collectionspace.services.nuxeo.client.java.RepositoryClientImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.collectionspace.services.workflow.WorkflowCommon;
-
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
-
 import org.jboss.resteasy.util.HttpResponseCodes;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
@@ -261,19 +260,20 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
 
        protected String lookupParentCSID(String parentspecifier, String method,
                        String op, UriInfo uriInfo) throws Exception {
-               CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(
+               CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(null,
                                parentspecifier, method, op, uriInfo);
                return tempResult.CSID;
        }
 
     private CsidAndShortIdentifier lookupParentCSIDAndShortIdentifer(
-               String parentspecifier,
+               ServiceContext itemServiceCtx,
+               String parentSpecifier,
                String method,
                String op,
                UriInfo uriInfo)
             throws Exception {
         CsidAndShortIdentifier result = new CsidAndShortIdentifier();
-        Specifier parentSpec = getSpecifier(parentspecifier, method, op);
+        Specifier parentSpec = getSpecifier(parentSpecifier, method, op);
         // Note that we have to create the service context for the Items, not the main service
         String parentcsid;
         String parentShortIdentifier;
@@ -287,8 +287,13 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             parentShortIdentifier = parentSpec.value;
             String whereClause = RefNameServiceUtils.buildWhereForAuthByName(authorityCommonSchemaName, parentSpec.value);
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getServiceName(), uriInfo);
-            parentcsid = getRepositoryClient(ctx).findDocCSID(null, ctx, whereClause); //FIXME: REM - If the parent has been soft-deleted, should we be looking for the item?
+            CoreSessionInterface repoSession = null;
+            if (itemServiceCtx != null) {
+                repoSession = (CoreSessionInterface) itemServiceCtx.getCurrentRepositorySession();  // We want to use the thread's current repo session
+            }
+            parentcsid = getRepositoryClient(ctx).findDocCSID(repoSession, ctx, whereClause); //FIXME: REM - If the parent has been soft-deleted, should we be looking for the item?
         }
+        
         result.CSID = parentcsid;
         result.shortIdentifier = parentShortIdentifier;
         return result;
@@ -369,35 +374,38 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
      */
     @GET
     @Path("{csid}/sync")
-    public Response synchronize(
+    public byte[] synchronize(
             @Context Request request,
             @Context UriInfo ui,
             @PathParam("csid") String csid) {
-        PoxPayloadOut result = null;
+       byte[] result;
+       boolean neededSync = false;
+        PoxPayloadOut payloadOut = null;
         Specifier specifier;
         
         try {
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(ui);
             AuthorityDocumentModelHandler handler = (AuthorityDocumentModelHandler)createDocumentHandler(ctx);
             specifier = getSpecifier(csid, "getAuthority", "GET");
-            
-            getRepositoryClient(ctx).synchronize(ctx, specifier, handler);
-            result = ctx.getOutput();
-
+            neededSync = getRepositoryClient(ctx).synchronize(ctx, specifier, handler);
+            payloadOut = ctx.getOutput();
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.SYNC_FAILED, csid);
         }
 
-        if (result == null) {
-            Response response = Response.status(Response.Status.NOT_FOUND).entity(
-                    "Get failed, the requested Authority specifier:" + specifier + ": was not found.").type(
-                    "text/plain").build();
+        //
+        // If a sync was needed and was successful, return a copy of the updated resource.  Acts like an UPDATE.
+        //
+        if (neededSync == true) {
+               result = payloadOut.getBytes();
+        } else {
+               result = String.format("Authority resource '%s' was already in sync with shared authority server.",
+                               specifier.value).getBytes();
+               Response response = Response.status(Response.Status.NOT_MODIFIED).entity(result).type("text/plain").build();
             throw new CSWebApplicationException(response);
         }
-
-        return Response.status(Response.Status.OK).entity(
-                "Synchronization completed, the requested Authority specifier:" + specifier.value + ": was synchronized.").type(
-                "text/plain").build();
+        
+        return result;
     }
     
     /**
@@ -606,7 +614,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), input, resourceMap, uriInfo);
 
             // Note: must have the parentShortId, to do the create.
-            CsidAndShortIdentifier parent = lookupParentCSIDAndShortIdentifer(parentspecifier, "createAuthorityItem", "CREATE_ITEM", null);
+            CsidAndShortIdentifier parent = lookupParentCSIDAndShortIdentifer(null, parentspecifier, "createAuthorityItem", "CREATE_ITEM", null);
             DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = 
                createItemDocumentHandler(ctx, parent.CSID, parent.shortIdentifier);
             String itemcsid = getRepositoryClient(ctx).create(ctx, handler);
@@ -705,7 +713,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             RemoteServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = 
                (RemoteServiceContext<PoxPayloadIn, PoxPayloadOut>) createServiceContext(getItemServiceName(), resourceMap, uriInfo);
             
-            JaxRsContext jaxRsContext = new JaxRsContext(request, uriInfo); // REM - Why are we setting this?  Who is using the getter?
+            JaxRsContext jaxRsContext = new JaxRsContext(request, uriInfo); // Needed for getting account permissions part of the payload
             ctx.setJaxRsContext(jaxRsContext);
 
             // We omit the parentShortId, only needed when doing a create...
@@ -920,6 +928,56 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         return authRefList;
     }
 
+    /**
+     * Synchronizes the authority and its terms with a Shared Authority Server (SAS).
+     * 
+     * @param specifier either CSIDs and/or one of the urn forms
+     * 
+     * @return the authority item if it was synchronized with SAS
+     */
+    @GET
+    @Path("{csid}/items/{itemcsid}/sync")
+    public byte[] synchronizeItem(
+               @Context ResourceMap resourceMap,
+            @Context Request request,
+            @Context UriInfo uriInfo,
+            @PathParam("csid") String parentIdentifier,
+            @PathParam("itemcsid") String itemIdentifier
+            ) {
+       byte[] result;
+       boolean neededSync = false;
+        PoxPayloadOut payloadOut = null;
+        AuthorityItemSpecifier specifier;
+        CsidAndShortIdentifier parent;
+        
+        try {
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), null, resourceMap, uriInfo);
+            parent = lookupParentCSIDAndShortIdentifer(null, parentIdentifier, "syncAuthorityItem(parent)", "SYNC_ITEM", null);
+            AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parent.CSID, parent.shortIdentifier);
+            Specifier parentSpecifier = getSpecifier(parent.CSID, "getAuthority", "GET");
+            Specifier itemSpecifier = getSpecifier(itemIdentifier, "getAuthorityItem", "GET");
+            specifier = new AuthorityItemSpecifier(parentSpecifier, itemSpecifier);
+            neededSync = getRepositoryClient(ctx).synchronize(ctx, specifier, handler);
+            payloadOut = ctx.getOutput();
+        } catch (Exception e) {
+            throw bigReThrow(e, ServiceMessages.SYNC_FAILED, itemIdentifier);
+        }
+
+        //
+        // If a sync was needed and was successful, return a copy of the updated resource.  Acts like an UPDATE.
+        //
+        if (neededSync == true) {
+               result = payloadOut.getBytes();
+        } else {
+               result = String.format("Authority item resource '%s' was already in sync with shared authority server.",
+                               itemIdentifier).getBytes();
+               Response response = Response.status(Response.Status.NOT_MODIFIED).entity(result).type("text/plain").build();
+            throw new CSWebApplicationException(response);
+        }
+        
+        return result;
+    }
+    
     /**
      * Update authorityItem.
      * 
@@ -933,31 +991,51 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
     public byte[] updateAuthorityItem(
                @Context ResourceMap resourceMap, 
             @Context UriInfo uriInfo,
-            @PathParam("csid") String parentspecifier,
-            @PathParam("itemcsid") String itemspecifier,
+            @PathParam("csid") String parentSpecifier,
+            @PathParam("itemcsid") String itemSpecifier,
             String xmlPayload) {
         PoxPayloadOut result = null;
+        
         try {
             PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
-            // Note that we have to create the service context for the Items, not the main service
-            // Laramie CSPACE-3175.  passing null for queryParams, because prior to this refactor, the code moved to lookupParentCSID in this instance called the version of getServiceContext() that passes null
-            CsidAndShortIdentifier csidAndShortId = lookupParentCSIDAndShortIdentifer(parentspecifier, "updateAuthorityItem(parent)", "UPDATE_ITEM", null);
-            String parentcsid = csidAndShortId.CSID;
-            String parentShortId = csidAndShortId.shortIdentifier;
-
-            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo);
-            String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "updateAuthorityItem(item)", "UPDATE_ITEM", ctx);
-
-            // We omit the parentShortId, only needed when doing a create...
-            DocumentHandler<?, AbstractCommonList, DocumentModel, DocumentModelList> handler = createItemDocumentHandler(ctx, parentcsid, parentShortId);
-            getRepositoryClient(ctx).update(ctx, itemcsid, handler);
-            result = ctx.getOutput();
-
+            result = updateAuthorityItem(null, resourceMap, uriInfo, parentSpecifier, itemSpecifier, theUpdate, true); // passing TRUE so parent authority rev num increases
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED);
         }
+        
         return result.getBytes();
     }
+    
+    public PoxPayloadOut updateAuthorityItem(
+               ServiceContext itemServiceCtx, // Ok to be null
+               ResourceMap resourceMap, 
+            UriInfo uriInfo,
+            String parentspecifier,
+            String itemspecifier,
+            PoxPayloadIn theUpdate,
+            boolean shouldUpdateParentRev) throws Exception {
+        PoxPayloadOut result = null;
+        
+        CsidAndShortIdentifier csidAndShortId = lookupParentCSIDAndShortIdentifer(itemServiceCtx, parentspecifier, "updateAuthorityItem(parent)", "UPDATE_ITEM", null);
+        String parentcsid = csidAndShortId.CSID;
+        String parentShortId = csidAndShortId.shortIdentifier;
+        //
+        // If the itemServiceCtx context is not null, use it.  Otherwise, create a new context
+        //
+        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = itemServiceCtx;
+        if (ctx == null) {
+               ctx = createServiceContext(getItemServiceName(), theUpdate, resourceMap, uriInfo);
+        }
+        String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "updateAuthorityItem(item)", "UPDATE_ITEM", ctx); //use itemServiceCtx if it is not null
+
+        // We omit the parentShortId, only needed when doing a create...
+        AuthorityItemDocumentModelHandler handler = (AuthorityItemDocumentModelHandler)createItemDocumentHandler(ctx, parentcsid, parentShortId);
+        handler.setShouldUpdateParentRevNumber(shouldUpdateParentRev);
+        getRepositoryClient(ctx).update(ctx, itemcsid, handler);
+        result = ctx.getOutput();
+
+        return result;
+    }
 
     /**
      * Delete authorityItem.
index 3b8b8b9ce43e86fe507f54546742a719f1ef6f0e..35c85b80c6f9c777ce2370157806b7d0d6d437a0 100644 (file)
@@ -33,6 +33,8 @@ import org.collectionspace.services.client.PayloadInputPart;
 import org.collectionspace.services.client.VocabularyClient;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.XmlTools;
 import org.collectionspace.services.common.api.RefName;
 import org.collectionspace.services.common.api.RefName.Authority;
 import org.collectionspace.services.common.api.RefNameUtils;
@@ -44,6 +46,8 @@ import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
+import org.collectionspace.services.common.vocabulary.AuthorityResource;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
 import org.collectionspace.services.config.service.ObjectPartType;
@@ -57,7 +61,6 @@ import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.testng.Assert;
 
 /**
  * AuthorityDocumentModelHandler
@@ -95,26 +98,43 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon>
     }
     
     @Override
-    public void handleSync(DocumentWrapper<Specifier> wrapDoc) throws Exception {
-       
-       ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
-        Specifier specifier = wrapDoc.getWrappedObject();
+    public boolean handleSync(DocumentWrapper<Object> wrapDoc) throws Exception {
+       boolean result = false;
+       ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
+        Specifier specifier = (Specifier) wrapDoc.getWrappedObject();
         //
         // Get the rev number of the authority so we can compare with rev number of shared authority
         //
         DocumentModel docModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), authorityCommonSchemaName, specifier);
-        Long rev = (Long) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.REV);
-        String shortId = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
-        String refName = (String) NuxeoUtils.getProperyValue(docModel, AuthorityItemJAXBSchema.REF_NAME);
-        AuthorityInfo authorityInfo = RefNameUtils.parseAuthorityInfo(refName);
+        Long rev = (Long) NuxeoUtils.getProperyValue(docModel, AuthorityJAXBSchema.REV);
+        String shortId = (String) NuxeoUtils.getProperyValue(docModel, AuthorityJAXBSchema.SHORT_IDENTIFIER);
+        String refName = (String) NuxeoUtils.getProperyValue(docModel, AuthorityJAXBSchema.REF_NAME);
         //
         // Using the short ID of the local authority, created a URN specifier to retrieve the SAS authority
         //
         Specifier sasSpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(shortId));
-        Long sasRev = getRevFromSASInstance(sasSpecifier);
+        PoxPayloadIn sasPayloadIn = getPayloadIn(ctx, sasSpecifier);
+
+        Long sasRev = getRevision(sasPayloadIn);
+        if (sasRev > rev) {
+               ResourceMap resourceMap = ctx.getResourceMap();
+               String resourceName = ctx.getClient().getServiceName();
+               AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName);
+               PoxPayloadOut payloadOut = authorityResource.update(ctx, resourceMap, null, docModel.getName(), sasPayloadIn);
+               if (payloadOut != null) {
+                       ctx.setOutput(payloadOut);
+                       result = true;
+               }
+        }
+        
+        return result;
+    }
         
-        AuthorityClient client = ctx.getAuthorityClient();
-        Response res = client.read(sasSpecifier.value);
+    private PoxPayloadIn getPayloadIn(ServiceContext ctx, Specifier specifier) throws Exception {
+       PoxPayloadIn result = null;
+       
+        AuthorityClient client = (AuthorityClient) ctx.getClient();
+        Response res = client.read(specifier.value);
         try {
                int statusCode = res.getStatus();
        
@@ -124,26 +144,10 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon>
                    logger.debug(client.getClass().getCanonicalName() + ": status = " + statusCode);
                }
                
-            PoxPayloadIn input = new PoxPayloadIn((String)res.readEntity(getEntityResponseType())); // Get the entire response!
-               
-                       PayloadInputPart payloadInputPart = extractPart(res, client.getCommonPartName());
-                       if (payloadInputPart != null) {
-//                             result = (client.getc) payloadInputPart.getBody();
-                       }
-                       Document document = input.getDOMDocument();
-                       Element rootElement = document.getRootElement();
-
+            result = new PoxPayloadIn((String)res.readEntity(getEntityResponseType())); // Get the entire response!            
         } finally {
                res.close();
         }
-        
-    }
-    
-    private Long getRevFromSASInstance(Specifier specifier) {
-       Long result = null;
-       
-       VocabularyClient client = new VocabularyClient();
-       String uri = getUri(specifier);
        
        return result;
     }
@@ -315,6 +319,9 @@ public abstract class AuthorityDocumentModelHandler<AuthCommon>
                repoSession = nuxeoRepoClient.getRepositorySession(ctx);
             DocumentWrapper<DocumentModel> wrapDoc = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, authCSID);
             DocumentModel docModel = wrapDoc.getWrappedObject();
+            if (docModel == null) {
+               throw new DocumentNotFoundException(String.format("Could not find authority resource with CSID='%s'.", authCSID));
+            }
             shortIdentifier = (String) docModel.getProperty(schemaName, AuthorityJAXBSchema.SHORT_IDENTIFIER);
         } catch (ClientException ce) {
             throw new RuntimeException("AuthorityDocHandler Internal Error: cannot get shortId!", ce);
index 99b6865b633f3354f1aa99bc752586a5eae8dc72..b1b0bdfb9598f413f4ed6551bd4c0c2e78fc752a 100644 (file)
@@ -27,14 +27,20 @@ import org.collectionspace.services.client.AuthorityClient;
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.common.ResourceMap;
 import org.collectionspace.services.common.UriTemplateRegistry;
 import org.collectionspace.services.common.api.RefName;
+import org.collectionspace.services.common.api.RefNameUtils;
+import org.collectionspace.services.common.api.RefNameUtils.AuthorityTermInfo;
 import org.collectionspace.services.common.api.Tools;
+import org.collectionspace.services.common.api.RefNameUtils.AuthorityInfo;
 import org.collectionspace.services.common.authorityref.AuthorityRefDocList;
 import org.collectionspace.services.common.context.MultipartServiceContext;
+import org.collectionspace.services.common.context.MultipartServiceContextImpl;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.DocumentException;
 import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.DocumentHandler.Action;
 import org.collectionspace.services.common.repository.RepositoryClient;
@@ -42,6 +48,9 @@ import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityResource;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.SpecifierForm;
 import org.collectionspace.services.config.service.ListResultField;
 import org.collectionspace.services.config.service.ObjectPartType;
 import org.collectionspace.services.nuxeo.client.java.NuxeoDocumentModelHandler;
@@ -57,6 +66,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -78,8 +88,11 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         extends NuxeoDocumentModelHandler<AICommon> {
 
     private final Logger logger = LoggerFactory.getLogger(AuthorityItemDocumentModelHandler.class);
-    private String authorityItemCommonSchemaName;
+    
+    protected String authorityCommonSchemaName;
+    protected String authorityItemCommonSchemaName;
     private String authorityItemTermGroupXPathBase;
+    private boolean shouldUpdateParentRevNumber = true;
     /**
      * inVocabulary is the parent Authority for this context
      */
@@ -91,11 +104,19 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
     private final static String LIST_SUFFIX = "List";
     private final static String ZERO_OR_MORE_ANY_CHAR_REGEX = ".*";
 
-    public AuthorityItemDocumentModelHandler(String authorityItemCommonSchemaName) {
+    public AuthorityItemDocumentModelHandler(String authorityCommonSchemaName, String authorityItemCommonSchemaName) {
         this.authorityItemCommonSchemaName = authorityItemCommonSchemaName;
     }
     
     abstract public String getParentCommonSchemaName();
+    
+    public boolean getShouldUpdateParentRevNumber() {
+       return this.shouldUpdateParentRevNumber;
+    }
+    
+    public void setShouldUpdateParentRevNumber(boolean flag) {
+       this.shouldUpdateParentRevNumber = flag;
+    }
 
     @Override
     protected String getRefnameDisplayName(DocumentWrapper<DocumentModel> docWrapper) {
@@ -323,6 +344,85 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         return list;
     }
     
+    private PoxPayloadIn getPayloadIn(AuthorityItemSpecifier specifier) throws Exception {
+       PoxPayloadIn result = null;
+       
+       ServiceContext parentCtx = new MultipartServiceContextImpl(this.getAuthorityServicePath());
+        AuthorityClient client = (AuthorityClient) parentCtx.getClient();
+        Response res = client.readItem(specifier.getParentSpecifier().value, specifier.getItemSpecifier().value);
+        try {
+               int statusCode = res.getStatus();
+       
+               // Check the status code of the response: does it match
+               // the expected response(s)?
+               if (logger.isDebugEnabled()) {
+                   logger.debug(client.getClass().getCanonicalName() + ": status = " + statusCode);
+               }
+               
+            result = new PoxPayloadIn((String)res.readEntity(getEntityResponseType())); // Get the entire response!            
+        } finally {
+               res.close();
+        }
+       
+       return result;
+    }
+
+    @Override
+    public boolean handleSync(DocumentWrapper<Object> wrapDoc) throws Exception {
+       boolean result = false;
+       ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = getServiceContext();
+       AuthorityItemSpecifier authorityItemSpecifier = (AuthorityItemSpecifier) wrapDoc.getWrappedObject();
+        //
+        // Get the rev number of the authority item so we can compare with rev number of shared authority
+        //
+        DocumentModel itemDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), getAuthorityItemCommonSchemaName(), 
+                       authorityItemSpecifier.getItemSpecifier());
+        if (itemDocModel == null) {
+               throw new DocumentNotFoundException(String.format("Could not find authority item resource with CSID='%s'",
+                               authorityItemSpecifier.getItemSpecifier().value));
+        }
+        Long itemRev = (Long) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.REV);
+        String itemShortId = (String) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.SHORT_IDENTIFIER);
+        String itemRefName = (String) NuxeoUtils.getProperyValue(itemDocModel, AuthorityItemJAXBSchema.REF_NAME);
+        //
+        // Now get the Authority (the parent) information
+        //
+        DocumentModel authorityDocModel = NuxeoUtils.getDocFromSpecifier(ctx, getRepositorySession(), authorityCommonSchemaName,
+                       authorityItemSpecifier.getParentSpecifier());
+        Long authorityRev = (Long) NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.REV);
+        String authorityShortId = (String) NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.SHORT_IDENTIFIER);
+        String authorityRefName = (String) NuxeoUtils.getProperyValue(authorityDocModel, AuthorityJAXBSchema.REF_NAME);
+        AuthorityInfo authorityInfo = RefNameUtils.parseAuthorityInfo(authorityRefName);
+        //
+        // Using the short IDs of the local authority and item, create URN specifiers to retrieve the SAS authority item
+        //
+        Specifier sasAuthoritySpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(authorityShortId));
+        Specifier sasItemSpecifier = new Specifier(SpecifierForm.URN_NAME, RefNameUtils.createShortIdRefName(itemShortId));
+        AuthorityItemSpecifier sasAuthorityItemSpecifier = new AuthorityItemSpecifier(sasAuthoritySpecifier, sasItemSpecifier);
+        // Get the shared authority server's copy
+        PoxPayloadIn sasPayloadIn = getPayloadIn(sasAuthorityItemSpecifier);
+
+        Long sasRev = getRevision(sasPayloadIn);
+        if (sasRev > itemRev) {
+               ResourceMap resourceMap = ctx.getResourceMap();
+               String resourceName = this.getAuthorityServicePath();
+               AuthorityResource authorityResource = (AuthorityResource) resourceMap.get(resourceName);
+               PoxPayloadOut payloadOut = authorityResource.updateAuthorityItem(ctx, 
+                               resourceMap,                                    
+                               null, 
+                               authorityDocModel.getName(),    // parent's CSID
+                               itemDocModel.getName(),                 // item's CSID
+                               sasPayloadIn,                                   // the payload from the SAS
+                               false);                                                 // don't update the parent's revision number
+               if (payloadOut != null) {
+                       ctx.setOutput(payloadOut);
+                       result = true;
+               }
+        }
+        
+        return result;
+    }
+    
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#handleCreate(org.collectionspace.services.common.document.DocumentWrapper)
      */
@@ -418,11 +518,13 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
        //
        // Next, update the inAuthority (the parent's) rev number
        //
-       DocumentModel inAuthorityDocModel = NuxeoUtils.getDocFromCsid(getServiceContext(), getRepositorySession(), getInAuthority());
-       Long parentRev = (Long)inAuthorityDocModel.getProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV);
-               parentRev++;
-               inAuthorityDocModel.setProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV, parentRev);
-               getRepositorySession().saveDocument(inAuthorityDocModel);
+       if (this.shouldUpdateParentRevNumber == true) {
+               DocumentModel inAuthorityDocModel = NuxeoUtils.getDocFromCsid(getServiceContext(), getRepositorySession(), getInAuthority());
+               Long parentRev = (Long)inAuthorityDocModel.getProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV);
+                       parentRev++;
+                       inAuthorityDocModel.setProperty(getParentCommonSchemaName(), AuthorityJAXBSchema.REV, parentRev);
+                       getRepositorySession().saveDocument(inAuthorityDocModel);
+       }
     }    
     
     /**
index 13482dec3acc778c9296e428fe25d88175c2a367..9723ad18086ec36b49fa760c60de6f9b277121fc 100644 (file)
@@ -35,7 +35,7 @@ public class CitationDocumentModelHandler
                extends AuthorityItemDocumentModelHandler<CitationsCommon> {
     
     public CitationDocumentModelHandler() {
-       super(CitationAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(CitationAuthorityClient.SERVICE_COMMON_PART_NAME, CitationAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index 66c72036e72d5a278a24da4a41324d157a3eadf6..94386d1440e6709517ee450423b54ed9720ff2e5 100644 (file)
@@ -221,24 +221,49 @@ public abstract class NuxeoBasedResource
                @PathParam("csid") String csid,
                String xmlPayload) {
         PoxPayloadOut result = null;
+        
         ensureCSID(csid, UPDATE);
         try {
             PoxPayloadIn theUpdate = new PoxPayloadIn(xmlPayload);
-            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(theUpdate, uriInfo);
-            ctx.setResourceMap(resourceMap);
-            if (parentCtx != null && parentCtx.getCurrentRepositorySession() != null) {
-               ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); // Reuse the current repo session if one exists
-            }            
-            result = update(csid, theUpdate, ctx); //==> CALL implementation method, which subclasses may override.
+            result = update(parentCtx, resourceMap, uriInfo, csid, theUpdate);
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.UPDATE_FAILED, csid);
         }
+        
         return result.getBytes();
     }
+    
+    /**
+     * This method is used to synchronize data with the SAS (Shared Authority Server).
+     * 
+     * @param parentCtx
+     * @param resourceMap
+     * @param uriInfo
+     * @param csid
+     * @param theUpdate
+     * @return
+     * @throws Exception
+     */
+    public PoxPayloadOut update(ServiceContext<PoxPayloadIn, PoxPayloadOut> parentCtx, // REM: 4/6/2016 - Some sub-classes will override this method -e.g., MediaResource does.
+               ResourceMap resourceMap,
+               UriInfo uriInfo,
+               String csid,
+               PoxPayloadIn theUpdate) throws Exception {
+       PoxPayloadOut result = null;
+       
+        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(theUpdate, uriInfo);
+        ctx.setResourceMap(resourceMap);
+        if (parentCtx != null && parentCtx.getCurrentRepositorySession() != null) {
+               ctx.setCurrentRepositorySession(parentCtx.getCurrentRepositorySession()); // Reuse the current repo session if one exists
+        }            
+        result = update(csid, theUpdate, ctx); //==> CALL implementation method, which subclasses may override.
+       
+       return result;
+    }
 
     /** Subclasses may override this overload, which gets called from #udpate(String,MultipartInput)   */
     protected PoxPayloadOut update(String csid,
-            PoxPayloadIn theUpdate,
+            PoxPayloadIn theUpdate, // not used in this method, but could be used by an overriding method
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx)
             throws Exception {
         DocumentHandler handler = createDocumentHandler(ctx);
index 78f36f5c9b7622bf90440807e51e458a12aa8342..427a87e5ca1b7ecf955ac6f6b07ba721eeef72e6 100644 (file)
@@ -754,6 +754,14 @@ public class ServiceMain {
         return tenantBindingConfigReader;
     }
     
+    public ResourceMap getJaxRSResourceMap() {
+        ResourceMap result;
+        
+        result = ResteasyProviderFactory.getContextData(ResourceMap.class);
+        
+        return result;
+    }
+    
     /**
      *  Populate a registry of URI templates by querying each resource
      *  for its own entries in the registry.
@@ -764,7 +772,7 @@ public class ServiceMain {
     private synchronized void populateUriTemplateRegistry() {
        if (uriTemplateRegistry.isEmpty()) {
             NuxeoBasedResource resource = null;
-            ResourceMap resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+            ResourceMap resourceMap = getJaxRSResourceMap();
             for (Map.Entry<String, NuxeoBasedResource> entry : resourceMap.entrySet()) {
                 resource = entry.getValue();
                 Map<UriTemplateRegistryKey, StoredValuesUriTemplate> entries =
index 9a18c008a81b7818feb43550a9c2274542025844..f3d620990264dd58894f70d9ffb6ba1ddea5b585 100644 (file)
@@ -627,7 +627,7 @@ public abstract class AbstractServiceContextImpl<IT, OT>
     }
     
     @Override
-    public AuthorityClient getAuthorityClient() throws Exception {
+    public AuthorityClient getClient() throws Exception {
        AuthorityClient result = authorityClient;
        
         if (authorityClient == null) {
index 3898cb85a8fa0b3fb5f727add056c991eaa89849..97322e405ad729a0b7251ecb77e012e241afdd30 100644 (file)
@@ -55,6 +55,13 @@ public class MultipartServiceContextImpl
     final Logger logger = LoggerFactory.getLogger(MultipartServiceContextImpl.class);
        private String repositoryWorkspaceName;
 
+       
+    public MultipartServiceContextImpl(String serviceName)
+               throws DocumentException, UnauthorizedException {
+       super(serviceName, null);
+       setOutput(new PoxPayloadOut(serviceName));
+    }
+
     /**
      * Instantiates a new multipart service context impl.
      * 
index b0cfee337ce10c7d5cb8e923f5d2160347f50e6e..dd5c3479992f9d142bae422f0613f949dc9bfe97 100644 (file)
@@ -177,7 +177,13 @@ public class RemoteServiceContextImpl<IT, OT>
      * @return the map of service names to resource classes.
      */
     public ResourceMap getResourceMap() {
-       return resourceMap;
+       ResourceMap result = resourceMap;
+       
+       if (result == null) {
+               result = ServiceMain.getInstance().getJaxRSResourceMap();
+       }
+       
+       return result;
     }
 
     /**
index 241206a364b56e7a2c14c614fb591769fb242aca..0cb4cf8f2b89d93005e76052f9dc2350fff3ed0a 100644 (file)
@@ -29,7 +29,7 @@ import java.util.Map;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.UriInfo;
 
-import org.collectionspace.services.client.AuthorityClient;
+import org.collectionspace.services.client.CollectionSpaceClient;
 import org.collectionspace.services.common.ResourceMap;
 import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.ValidatorHandler;
@@ -353,7 +353,7 @@ public interface ServiceContext<IT, OT> {
 
        public void setRepositoryDomain(RepositoryDomainType repositoryDomain);
 
-       public AuthorityClient getAuthorityClient() throws Exception;
+       public CollectionSpaceClient getClient() throws Exception;
 }
 
 
index 56368f4f6a9d6c465c5e05f535e71d10c8b70545..61ff77bb81d90c57e7ce04578df0652c5793b5d7 100644 (file)
@@ -227,7 +227,9 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
      * @see org.collectionspace.services.common.document.DocumentHandler#handle(org.collectionspace.services.common.document.DocumentHandler.Action, org.collectionspace.services.common.document.DocumentWrapper)
      */
     @Override
-    final public void handle(Action action, DocumentWrapper<?> wrapDoc) throws Exception {
+    final public boolean handle(Action action, DocumentWrapper<?> wrapDoc) throws Exception {
+       boolean result = true;
+       
         switch (action) {
             case CREATE:
                 handleCreate((DocumentWrapper<WT>) wrapDoc);
@@ -250,7 +252,7 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
                 break;
                 
             case SYNC:
-                handleSync((DocumentWrapper<Specifier>) wrapDoc);
+                result = handleSync((DocumentWrapper<Object>) wrapDoc);
                 break;                
                 
                        case WORKFLOW:
@@ -263,6 +265,8 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
                                Thread.dumpStack();
                                break;
         }
+        
+        return result;
     }
 
     /* (non-Javadoc)
@@ -301,8 +305,9 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
      * @see org.collectionspace.services.common.document.DocumentHandler#handleDelete(org.collectionspace.services.common.document.DocumentWrapper)
      */
     @Override
-    public void handleSync(DocumentWrapper<Specifier> wrapDoc) throws Exception {
+    public boolean handleSync(DocumentWrapper<Object> wrapDoc) throws Exception {
        // Do nothing. Subclasses can override if they want/need to.
+       return true;
     }
     
 
@@ -333,7 +338,7 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
                 break;
                 
             case SYNC:
-                completeSync((DocumentWrapper<Specifier>) wrapDoc);
+                completeSync((DocumentWrapper<Object>) wrapDoc);
                 break;
                 
                        case WORKFLOW:
@@ -388,7 +393,7 @@ public abstract class AbstractDocumentHandlerImpl<T, TL, WT, WTL>
      * @see org.collectionspace.services.common.document.DocumentHandler#completeDelete(org.collectionspace.services.common.document.DocumentWrapper)
      */
     @Override
-    public void completeSync(DocumentWrapper<Specifier> wrapDoc) throws Exception {
+    public void completeSync(DocumentWrapper<Object> wrapDoc) throws Exception {
     }    
 
     /* (non-Javadoc)
index cf09bc1f0c7b84f79cad372bee76c1863da66263..386151d824a8f88a838f8a114c88a42bbadc6cd6 100644 (file)
@@ -125,7 +125,7 @@ public interface DocumentHandler<T, TL, WT, WTL> {
      * @param doc wrapped doc
      * @throws Exception
      */
-    public void handle(Action action, DocumentWrapper<?> docWrap) throws Exception;
+    public boolean handle(Action action, DocumentWrapper<?> docWrap) throws Exception;
 
     /**
      * handleCreate processes documents before creating document in repository
@@ -375,13 +375,13 @@ public interface DocumentHandler<T, TL, WT, WTL> {
         * @param wrapDoc
         * @throws Exception
         */
-       void handleSync(DocumentWrapper<Specifier> wrapDoc) throws Exception;
+       boolean handleSync(DocumentWrapper<Object> wrapDoc) throws Exception;
 
        /**
         * 
         * @param wrapDoc
         * @throws Exception
         */
-       void completeSync(DocumentWrapper<Specifier> wrapDoc) throws Exception;
+       void completeSync(DocumentWrapper<Object> wrapDoc) throws Exception;
 
 }
index ffb433a75879e692419f7104df03658d8ac25122..f0caf18458334050469fbd3e7130aec191d55673 100644 (file)
@@ -25,6 +25,7 @@ import org.collectionspace.services.common.document.DocumentException;
 import org.collectionspace.services.common.document.DocumentHandler;
 import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.TransactionException;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
 import org.collectionspace.services.lifecycle.TransitionDef;
 
@@ -145,9 +146,16 @@ public interface StorageClient {
                throws BadRequestException, DocumentNotFoundException, DocumentException;
 
     /*
-     * Ask a resource to synchronize itself with a shared server resource
+     * Ask a resource to synchronize itself with a shared server resource.  Returns "TRUE" if sync was needed.
      */
-       void synchronize(ServiceContext ctx, Specifier specifier, DocumentHandler handler)
+       boolean synchronize(ServiceContext ctx, Object specifier, DocumentHandler handler)
+                       throws DocumentNotFoundException, TransactionException,
+                       DocumentException;
+
+    /*
+     * Ask an item resource (e.g., an Authority or Vocabulary items) to synchronize itself with a shared server resource.  Returns "TRUE" if sync was needed.
+     */
+       boolean synchronizeItem(ServiceContext ctx, AuthorityItemSpecifier itemSpecifier, DocumentHandler handler)
                        throws DocumentNotFoundException, TransactionException,
                        DocumentException;
 
index ba237810e42a595d03179d3811dfbcdfb895f65a..560c355ee4abc9f3b31789110789573317796ef2 100644 (file)
@@ -39,6 +39,7 @@ import org.collectionspace.services.common.document.DocumentWrapperImpl;
 import org.collectionspace.services.common.document.JaxbUtils;
 import org.collectionspace.services.common.document.TransactionException;
 import org.collectionspace.services.common.storage.StorageClient;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
 import org.collectionspace.services.common.context.ServiceContextProperties;
 import org.collectionspace.services.common.context.ServiceContext;
@@ -597,10 +598,21 @@ public class JpaStorageClientImpl implements StorageClient {
        }
 
        @Override
-       public void synchronize(ServiceContext ctx, Specifier specifier,
+       public boolean synchronize(ServiceContext ctx, Object specifier,
                        DocumentHandler handler) throws DocumentNotFoundException,
                        TransactionException, DocumentException {
                // TODO Auto-generated method stub
                // Do nothing. Subclasses can override if they want/need to.
+               return true;
        }
+       
+       @Override
+       public boolean synchronizeItem(ServiceContext ctx, AuthorityItemSpecifier itemSpecifier,
+                       DocumentHandler handler) throws DocumentNotFoundException,
+                       TransactionException, DocumentException {
+               // TODO Auto-generated method stub
+               // Do nothing. Subclasses can override if they want/need to.
+               return true;
+       }
+
 }
index a490e7d2766ef39033cc01172daf8be84178a1eb..ccaf2639cd575ae8765ff887e41fc7fb9c324a86 100644 (file)
@@ -94,6 +94,24 @@ public class RefNameServiceUtils {
             this.value = value;
         }
     }
+    
+    public static class AuthorityItemSpecifier {
+       private Specifier parentSpecifier;
+       private Specifier itemSpecifier;
+       
+       public AuthorityItemSpecifier(Specifier parentSpecifier, Specifier itemSpecifier) {
+               this.parentSpecifier = parentSpecifier;
+               this.itemSpecifier = itemSpecifier;
+       }
+       
+       public Specifier getParentSpecifier() {
+               return this.parentSpecifier;
+       }
+       
+       public Specifier getItemSpecifier() {
+               return this.itemSpecifier;
+       }
+    }
 
     public static class AuthRefConfigInfo {
 
index a3e93d0359f04033c5e679ef8593e1f1f75f8e7d..e56a919369f74079ff5240cac665432a93e5ed87 100644 (file)
@@ -38,6 +38,7 @@ import org.collectionspace.services.client.IRelationsManager;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.common.ReflectionMapper;
+import org.collectionspace.services.common.XmlTools;
 import org.collectionspace.services.common.api.GregorianCalendarDateTimeUtils;
 import org.collectionspace.services.common.api.Tools;
 import org.collectionspace.services.common.config.ServiceConfigUtils;
@@ -53,10 +54,9 @@ import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.nuxeo.client.java.CommonList;
 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
-
+import org.dom4j.Document;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -107,6 +107,24 @@ public abstract class NuxeoDocumentModelHandler<T> extends RemoteDocumentModelHa
                this.commonPart = commonPart;
        }
 
+    /**
+     * The entity type expected from the JAX-RS Response object.  By default it is of type String.  Child classes
+     * can override this if they need to.
+     */
+    protected Class<String> getEntityResponseType() {
+       return String.class;
+    }
+    
+    protected Long getRevision(PoxPayloadIn payloadIn) {
+       Long result = null;
+       
+               Document document = payloadIn.getDOMDocument();
+               String xmlRev = XmlTools.getElementValue(document, "//rev");
+               result = Long.valueOf(xmlRev);
+               
+               return result;
+    }
+
        /**
         * Subclass DocHandlers may override this method to control exact creation of the common list.
         * This class instantiates an AbstractCommonList from the classname returned by getDocHandlerParams().AbstractCommonListClassname.
index fd1b384949ebcb99327119b6cadebfac0092a442..5de76630d5596359cd2f411ab1d597294ab13458 100644 (file)
@@ -62,6 +62,7 @@ import org.collectionspace.services.common.config.ConfigUtils;
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;
 import org.collectionspace.services.common.config.TenantBindingUtils;
 import org.collectionspace.services.common.storage.PreparedStatementBuilder;
+import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.AuthorityItemSpecifier;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils.Specifier;
 import org.collectionspace.services.config.tenant.TenantBindingType;
 import org.collectionspace.services.config.tenant.RepositoryDomainType;
@@ -258,9 +259,46 @@ public class RepositoryClientImpl implements RepositoryClient<PoxPayloadIn, PoxP
     }
     
     @Override
-    public void synchronize(ServiceContext ctx, Specifier specifier, DocumentHandler handler)
+    public boolean synchronize(ServiceContext ctx, Object specifier, DocumentHandler handler)
             throws DocumentNotFoundException, TransactionException, DocumentException {
+       boolean result = false;
+       
+        if (handler == null) {
+            throw new IllegalArgumentException(
+                    "RepositoryJavaClient.get: handler is missing");
+        }
 
+        CoreSessionInterface repoSession = null;
+        try {
+            handler.prepare(Action.SYNC);
+            repoSession = getRepositorySession(ctx);
+            ((DocumentModelHandler) handler).setRepositorySession(repoSession);
+            DocumentWrapper<Object> wrapDoc = new DocumentWrapperImpl<Object>(specifier);
+            result = handler.handle(Action.SYNC, wrapDoc);
+            handler.complete(Action.SYNC, wrapDoc);
+        } catch (IllegalArgumentException iae) {
+            throw iae;
+        } catch (DocumentException de) {
+            throw de;
+        } catch (Exception e) {
+            if (logger.isDebugEnabled()) {
+                logger.debug("Caught exception ", e);
+            }
+            throw new NuxeoDocumentException(e);
+        } finally {
+            if (repoSession != null) {
+                releaseRepositorySession(ctx, repoSession);
+            }
+        }
+        
+        return result;
+    }
+    
+    @Override
+    public boolean synchronizeItem(ServiceContext ctx, AuthorityItemSpecifier itemSpecifier, DocumentHandler handler)
+            throws DocumentNotFoundException, TransactionException, DocumentException {
+       boolean result = false;
+       
         if (handler == null) {
             throw new IllegalArgumentException(
                     "RepositoryJavaClient.get: handler is missing");
@@ -271,8 +309,8 @@ public class RepositoryClientImpl implements RepositoryClient<PoxPayloadIn, PoxP
             handler.prepare(Action.SYNC);
             repoSession = getRepositorySession(ctx);
             ((DocumentModelHandler) handler).setRepositorySession(repoSession);
-            DocumentWrapper<Specifier> wrapDoc = new DocumentWrapperImpl<Specifier>(specifier);
-            handler.handle(Action.SYNC, wrapDoc);
+            DocumentWrapper<AuthorityItemSpecifier> wrapDoc = new DocumentWrapperImpl<AuthorityItemSpecifier>(itemSpecifier);
+            result = handler.handle(Action.SYNC, wrapDoc);
             handler.complete(Action.SYNC, wrapDoc);
         } catch (IllegalArgumentException iae) {
             throw iae;
@@ -288,6 +326,8 @@ public class RepositoryClientImpl implements RepositoryClient<PoxPayloadIn, PoxP
                 releaseRepositorySession(ctx, repoSession);
             }
         }
+        
+        return result;
     }
     
     /**
@@ -1834,8 +1874,10 @@ public class RepositoryClientImpl implements RepositoryClient<PoxPayloadIn, PoxP
         // To get a connection to the Nuxeo repo, we need either a valid ServiceContext instance or a repository name
         //
         if (ctx != null) {
-            repoName = ctx.getRepositoryName(); // Notice we are overriding the passed in 'repoName' since we have a valid service context passed in to us
-            repoSession = (CoreSessionInterface) ctx.getCurrentRepositorySession(); // Look to see if one exists in the context before creating one
+               repoSession = (CoreSessionInterface) ctx.getCurrentRepositorySession(); // First see if the context already has a repo session
+               if (repoSession == null) {
+                   repoName = ctx.getRepositoryName(); // Notice we are overriding the passed in 'repoName' since we have a valid service context passed in to us
+               }
         } else if (repoName == null || repoName.trim().isEmpty()) {
             String errMsg = String.format("We can't get a connection to the Nuxeo repo because the service context passed in was null and no repository name was passed in either.");
             logger.error(errMsg);
index d7eeb0e9870a98a5207ecc6b7f8a31266ba84bb0..4bdefd8976471ba294ea361be7faf8e5962ec23c 100644 (file)
@@ -465,7 +465,7 @@ public class NuxeoUtils {
         //
         query.append(/*IQueryManager.SEARCH_QUALIFIER_AND +*/ " WHERE " + CollectionSpaceClient.COLLECTIONSPACE_CORE_SCHEMA + ":"
                 + CollectionSpaceClient.COLLECTIONSPACE_CORE_TENANTID
-                + " = " + queryContext.getTenantId());
+                + " = " + "'" + queryContext.getTenantId() + "'");
         //
         // Finally, append the incoming where clause
         //
index 105dfc54695490e37eb02eefec6a205aab3e1acd..6d13faf5fb025feb83239dff5ff59ae8a1f9d2b2 100644 (file)
@@ -35,7 +35,7 @@ public class ConceptDocumentModelHandler
         extends AuthorityItemDocumentModelHandler<ConceptsCommon> {
 
     public ConceptDocumentModelHandler() {
-       super(ConceptAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(ConceptAuthorityClient.SERVICE_COMMON_PART_NAME, ConceptAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index c7cd1c91411b0686069b744ed7197804f441394d..933e2c9bd880dceb18a50a79d9ebd50749d3463f 100644 (file)
@@ -35,7 +35,7 @@ public class LocationDocumentModelHandler
         extends AuthorityItemDocumentModelHandler<LocationsCommon> {
     
     public LocationDocumentModelHandler() {
-       super(LocationAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(LocationAuthorityClient.SERVICE_COMMON_PART_NAME, LocationAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index a2c9e74b70dc7dd466a4fbe4e8fdc6fe9c56d15c..611da504fe339d6052b7b8ada29740b5b100ea4f 100644 (file)
@@ -35,7 +35,7 @@ public class MaterialDocumentModelHandler
         extends AuthorityItemDocumentModelHandler<MaterialsCommon> {
 
     public MaterialDocumentModelHandler() {
-        super(MaterialAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+        super(MaterialAuthorityClient.SERVICE_COMMON_PART_NAME, MaterialAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index 0c2ecb6db9e8bc866a418eecfdeacb075ab21333..b47a4d52112fcaad87a56648085edf7d931cf8f6 100644 (file)
@@ -35,7 +35,7 @@ public class OrganizationDocumentModelHandler
                extends AuthorityItemDocumentModelHandler<OrganizationsCommon> {
 
     public OrganizationDocumentModelHandler() {
-       super(OrgAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(OrgAuthorityClient.SERVICE_COMMON_PART_NAME, OrgAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index 215975f19636f600ba5ec14a5d9c50b1614124c2..088abf5973414ebeadab3aed1e1227d324719aab 100644 (file)
@@ -35,7 +35,7 @@ public class PersonDocumentModelHandler
        extends AuthorityItemDocumentModelHandler<PersonsCommon> {
 
     public PersonDocumentModelHandler() {
-       super(PersonAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(PersonAuthorityClient.SERVICE_COMMON_PART_NAME, PersonAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index c60e5989918ac521b27ca7a16143776d2527f17b..acfbdbadd144083f4a78b8e6b56b517ccadca951 100644 (file)
@@ -35,7 +35,7 @@ public class PlaceDocumentModelHandler
         extends AuthorityItemDocumentModelHandler<PlacesCommon> {
 
     public PlaceDocumentModelHandler() {
-       super(PlaceAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(PlaceAuthorityClient.SERVICE_COMMON_PART_NAME, PlaceAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index 6a73471d52ea725f4bb70803d54c2a3591c7c2b8..cdcb79da6569d915dc904e1fa82c52c68aaa7ade 100644 (file)
@@ -35,7 +35,7 @@ public class TaxonDocumentModelHandler
         extends AuthorityItemDocumentModelHandler<TaxonCommon> {
 
     public TaxonDocumentModelHandler() {
-        super(TaxonomyAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+        super(TaxonomyAuthorityClient.SERVICE_COMMON_PART_NAME, TaxonomyAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
     
     @Override
index 591442e5d3e5fe89166137f1f92992a9acd1e5ad..00e49f8283130cd9d452602a5bbb2bb0f4d7d0fe 100644 (file)
@@ -40,7 +40,7 @@ public class VocabularyItemDocumentModelHandler
                extends AuthorityItemDocumentModelHandler<VocabularyitemsCommon> {
 
     public VocabularyItemDocumentModelHandler() {
-       super(VocabularyClient.SERVICE_ITEM_COMMON_PART_NAME);
+       super(VocabularyClient.SERVICE_COMMON_PART_NAME, VocabularyClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override
index 24507afe097b91e5b6160d5657e2958096e98c6c..3cd3648d9df4f64ee88a81adf40c0e5e40f443be 100644 (file)
@@ -35,7 +35,7 @@ public class WorkDocumentModelHandler
         extends AuthorityItemDocumentModelHandler<WorksCommon> {
 
     public WorkDocumentModelHandler() {
-        super(WorkAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
+        super(WorkAuthorityClient.SERVICE_COMMON_PART_NAME, WorkAuthorityClient.SERVICE_ITEM_COMMON_PART_NAME);
     }
 
     @Override