]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-2323, CSPACE-3016, etc., Fixes to properly integrate with new Nuxeo libs,...
authorPatrick Schmitz <pschmitz@berkeley.edu>
Sat, 10 Dec 2011 03:04:20 +0000 (03:04 +0000)
committerPatrick Schmitz <pschmitz@berkeley.edu>
Sat, 10 Dec 2011 03:04:20 +0000 (03:04 +0000)
Changed logging configuration to rotate among 10 files of 5MB each, so we have more context on the server. Also removed the stdout copy that was bloating catalina.out (on 1.13 QA, the file is over 1.1GB).
Added new tests to exercise refObjs and authRefs more carefully.
Tweaked XMLReplay to output clock times for each test, making it easier to align tests with log output.
Added some debug support for startup issues with Nuxeo and Workspaces.
Removed pointless output from LoanoutValidatorHandler.

22 files changed:
services/IntegrationTests/src/main/java/org/collectionspace/services/IntegrationTests/xmlreplay/XmlReplay.java
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/authrefs.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/authrefsSimple.xml
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/authrefsSimple2.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/loanin.xml [new file with mode: 0644]
services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/res/refObjs.res.xml [new file with mode: 0644]
services/JaxRsServiceProvider/src/main/resources/log4j.properties
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/AuthorityItemDocumentModelHandler.java
services/batch/service/src/main/java/org/collectionspace/services/batch/BatchResource.java
services/batch/service/src/main/java/org/collectionspace/services/batch/nuxeo/BatchDocumentModelHandler.java
services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java
services/common/src/main/java/org/collectionspace/services/common/repository/RepositoryClient.java
services/common/src/main/java/org/collectionspace/services/common/security/SecurityInterceptor.java
services/common/src/main/java/org/collectionspace/services/common/vocabulary/RefNameServiceUtils.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RemoteDocumentModelHandlerImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/TenantRepository.java
services/loanout/service/src/main/java/org/collectionspace/services/loanout/nuxeo/LoanoutValidatorHandler.java
services/relation/service/src/main/java/org/collectionspace/services/relation/nuxeo/RelationDocumentModelHandler.java
services/report/service/src/main/java/org/collectionspace/services/report/ReportResource.java
services/report/service/src/main/java/org/collectionspace/services/report/nuxeo/ReportDocumentModelHandler.java

index 41c18d30c2029ca11c7c2e57a2711adf97e8bba4..ccde889b374717045d65c69adedabc18005e5a10 100755 (executable)
@@ -693,7 +693,7 @@ public class XmlReplay {
                         || (dump.dumpServiceResult == ServiceResult.DUMP_OPTIONS.full)         ){\r
                         System.out.println("\r\n#---------------------#");\r
                     }\r
-                    System.out.println(leader+serviceResultRow+"\r\n");\r
+                    System.out.println(timeString()+" "+leader+serviceResultRow+"\r\n");\r
                     if (dump.payloads || (doingAuto&&hasError) ) {\r
                         if (Tools.notBlank(serviceResult.requestPayload)){\r
                             System.out.println("\r\n========== request payload ===============");\r
@@ -738,7 +738,12 @@ public class XmlReplay {
         return results;\r
     }\r
 \r
-\r
+               private static String timeString() {\r
+                       java.util.Date date= new java.util.Date();\r
+                       java.sql.Timestamp ts = new java.sql.Timestamp(date.getTime());\r
+                       return ts.toString();\r
+               }\r
+               \r
 \r
     //======================== MAIN ===================================================================\r
 \r
index 92e864af160a7b549154672cd26e2991c4be228c..414f53a51ab194e2cfedba5e089dc0f40d97cf49 100644 (file)
                        <filename>authrefs/updatePerson2.xml</filename>\r
                </test>\r
 \r
-<!-- FIXME: Tests failed in Tomcat 6/Nuxeo 5.4.2 branch after merging from trunk through r6056: Aron -->\r
-<!-- These appear to be testing propagation of updates to display names in authRefs, following an update within a person record -->\r
-<!--\r
         <test ID="GetFirstUpdatedPerson">\r
                        <method>GET</method>\r
                        <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}</uri>\r
                                </vars>\r
                         </response>\r
                </test>\r
--->\r
-<!--\r
-{TEXT_DIFFERENT, L.path:/borrowersContact, R.path:/borrowersContact, status:TEXT_DIFFERENT,\r
-    L.trimmed:urn:cspace:core.collectionspace.org:personauthorities:name(TestPersonAuth):item:name(debbieDoNothingPerson)'Debbie Do Nothing Personality',\r
-    R.trimmed:urn:cspace:core.collectionspace.org:personauthorities:name(TestPersonAuth):item:name(debbieDoNothingPerson)'Debbie DoNothingPerson'}\r
--->\r
-<!--\r
                <test ID="afterUpdateGetLoan5">\r
                        <method>GET</method>\r
                        <uri>/cspace-services/loansout/${loanout5.CSID}</uri>\r
                                </vars>\r
                         </response>\r
                </test>\r
--->\r
 \r
        </testGroup>\r
 </xmlReplay>\r
index 721c67ca31e6d4c9419733763c0a7307127f6f3c..66adebb962fcf47a39925fca07c5a21aeeefc106 100644 (file)
@@ -65,7 +65,7 @@
                        <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}/refObjs</uri>\r
                        <response>\r
                                <expected level="ADDOK" />\r
-                               <filename>authrefs/res/foo.res.xml</filename>\r
+                               <filename>authrefs/res/refObjs.res.xml</filename>\r
                         </response>\r
                </test>\r
 \r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/authrefsSimple2.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/authrefsSimple2.xml
new file mode 100644 (file)
index 0000000..8fab390
--- /dev/null
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<xmlReplay>\r
+       <!-- \r
+                        testGroup ID="person" is not live.  It works, but may not clean up correctly. \r
+                        For now, use ID="updatePerson"\r
+       -->\r
+       <testGroup ID="AuthRefsSimple2" autoDeletePOSTS="true">\r
+               <test ID="PersonAuth1" auth="admin@core.collectionspace.org">\r
+                       <method>POST</method>\r
+                       <uri>/cspace-services/personauthorities/</uri>\r
+                       <filename>authrefs/newPersonAuthority.xml</filename>\r
+               </test>\r
+               <test ID="Person1">\r
+                       <method>POST</method>\r
+                       <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/</uri>\r
+                       <filename>authrefs/newPerson1.xml</filename>\r
+               </test>\r
+\r
+        <test ID="GetPerson1">\r
+                       <method>GET</method>\r
+                       <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}</uri>\r
+               </test>\r
+\r
+               <test ID="loanin1" auth="test">\r
+                       <method>POST</method>\r
+                       <uri>/cspace-services/loansin/</uri>\r
+                       <filename>authrefs/loanin.xml</filename>\r
+                       <vars>\r
+                               <var ID="loannum">42</var>\r
+                               <var ID="person">${GetPerson1.got("//refName")}</var>\r
+                       </vars>\r
+               </test>\r
+\r
+               <test ID="getloanin1" auth="test">\r
+                       <method>GET</method>\r
+                       <uri>/cspace-services/loansin/${loanin1.CSID}/</uri>\r
+                       <response>\r
+                               <expected level="ADDOK" />\r
+                               <filename>authrefs/res/foo.res.xml</filename>\r
+                        </response>\r
+               </test>\r
+\r
+               <test ID="getLoan1AuthRefs">\r
+                       <method>GET</method>\r
+                       <uri>/cspace-services/loansin/${loanin1.CSID}/authorityrefs</uri>\r
+                       <response>\r
+                               <expected level="ADDOK" />\r
+                               <filename>authrefs/res/foo.res.xml</filename>\r
+                        </response>\r
+               </test>\r
+\r
+               <test ID="getPerson1RefObjs">\r
+                       <method>GET</method>\r
+                       <uri>/cspace-services/personauthorities/${PersonAuth1.CSID}/items/${Person1.CSID}/refObjs</uri>\r
+                       <response>\r
+                               <expected level="ADDOK" />\r
+                               <filename>authrefs/res/refObjs.res.xml</filename>\r
+                        </response>\r
+               </test>\r
+\r
+       </testGroup>\r
+</xmlReplay>\r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/loanin.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/loanin.xml
new file mode 100644 (file)
index 0000000..dc8d5f4
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<document name="loansin">\r
+    <ns2:loansin_common xmlns:ns2="http://collectionspace.org/services/loanin"\r
+        xmlns:ns3="http://collectionspace.org/services/jaxb">\r
+        <loanInNumber>loaninNumber-${loannum}</loanInNumber>\r
+        <lenderGroupList>\r
+            <lenderGroup>\r
+                <lendersAuthorizationDate>October 29, 2009</lendersAuthorizationDate>\r
+                <lender>${person}</lender>\r
+            </lenderGroup>\r
+        </lenderGroupList>\r
+        <loanPurpose>For Surfboards of the 1960s exhibition.</loanPurpose>\r
+        <loanInConditions>Loan in conditions.</loanInConditions>\r
+    </ns2:loansin_common>\r
+</document>\r
diff --git a/services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/res/refObjs.res.xml b/services/IntegrationTests/src/test/resources/test-data/xmlreplay/authrefs/res/refObjs.res.xml
new file mode 100644 (file)
index 0000000..635f8db
--- /dev/null
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r
+<ns3:authority-ref-doc-list xmlns:ns2="http://collectionspace.org/services/jaxb"\r
+    xmlns:ns3="http://collectionspace.org/services/common/authorityref">\r
+    <itemsInPage>1</itemsInPage>\r
+    <totalItems>1</totalItems>\r
+</ns3:authority-ref-doc-list>\r
index 2be5675d6d29620fb479ede95158ec4d1e89d589..848dd0718af5ae6535f180c12a645752ea08a531 100644 (file)
@@ -1,4 +1,4 @@
-log4j.rootLogger=debug, stdout, R\r
+log4j.rootLogger=debug, R\r
 \r
 log4j.appender.stdout=org.apache.log4j.ConsoleAppender\r
 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout\r
@@ -9,9 +9,9 @@ log4j.appender.stdout.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n
 log4j.appender.R=org.apache.log4j.RollingFileAppender\r
 log4j.appender.R.File=${catalina.home}/logs/cspace-services.log\r
 \r
-log4j.appender.R.MaxFileSize=1000KB\r
-# Keep one backup file\r
-log4j.appender.R.MaxBackupIndex=1\r
+log4j.appender.R.MaxFileSize=5000KB\r
+# Keep ten backup files\r
+log4j.appender.R.MaxBackupIndex=10\r
 \r
 log4j.appender.R.layout=org.apache.log4j.PatternLayout\r
 log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n\r
@@ -24,9 +24,11 @@ log4j.appender.R.layout.ConversionPattern=%d %-5p [%t] [%c:%L] %m%n
 # CollectionSpace log levels\r
 #\r
 log4j.logger.org.collectionspace=DEBUG\r
+#log4j.logger.org.collectionspace.services.common.vocabulary.nuxeo=TRACE\r
 log4j.logger.perf.collectionspace=ERROR\r
 \r
 log4j.logger.org.nuxeo=ERROR\r
+#log4j.logger.org.nuxeo.ecm.core.storage.sql=TRACE\r
 log4j.logger.org.apache=ERROR\r
 log4j.logger.httpclient=ERROR\r
 log4j.logger.org.jboss.resteasy=ERROR\r
index caf493758162ef5aedf14623f3a51f57d203a3af..b5119587dd078c28af7dc732728a34b7937468ce 100644 (file)
@@ -58,11 +58,13 @@ import org.collectionspace.services.common.workflow.service.nuxeo.WorkflowDocume
 import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler;
 import org.collectionspace.services.nuxeo.client.java.RemoteDocumentModelHandlerImpl;
+import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
 import org.collectionspace.services.relation.RelationResource;
 import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.relation.RelationshipType;
 import org.jboss.resteasy.util.HttpResponseCodes;
 import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -260,13 +262,13 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         String shortIdentifier;
     }
 
-    public String lookupParentCSID(String parentspecifier, String method, String op, MultivaluedMap<String, String> queryParams)
+    protected String lookupParentCSID(String parentspecifier, String method, String op, MultivaluedMap<String, String> queryParams)
             throws Exception {
         CsidAndShortIdentifier tempResult = lookupParentCSIDAndShortIdentifer(parentspecifier, method, op, queryParams);
         return tempResult.CSID;
     }
 
-    public CsidAndShortIdentifier lookupParentCSIDAndShortIdentifer(String parentspecifier, String method, String op, MultivaluedMap<String, String> queryParams)
+    private CsidAndShortIdentifier lookupParentCSIDAndShortIdentifer(String parentspecifier, String method, String op, MultivaluedMap<String, String> queryParams)
             throws Exception {
         CsidAndShortIdentifier result = new CsidAndShortIdentifier();
         Specifier parentSpec = getSpecifier(parentspecifier, method, op);
@@ -283,7 +285,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             parentShortIdentifier = parentSpec.value;
             String whereClause = buildWhereForAuthByName(parentSpec.value);
             ServiceContext ctx = createServiceContext(getServiceName(), queryParams);
-            parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause); //FIXME: REM - If the parent has been soft-deleted, should we be looking for the item?
+            parentcsid = getRepositoryClient(ctx).findDocCSID(null, ctx, whereClause); //FIXME: REM - If the parent has been soft-deleted, should we be looking for the item?
         }
         result.CSID = parentcsid;
         result.shortIdentifier = parentShortIdentifier;
@@ -298,7 +300,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             itemcsid = itemSpec.value;
         } else {
             String itemWhereClause = buildWhereForAuthItemByName(itemSpec.value, parentcsid);
-            itemcsid = getRepositoryClient(ctx).findDocCSID(ctx, itemWhereClause); //FIXME: REM - Should we be looking for the 'wf_deleted' query param and filtering on it?
+            itemcsid = getRepositoryClient(ctx).findDocCSID(null, ctx, itemWhereClause); //FIXME: REM - Should we be looking for the 'wf_deleted' query param and filtering on it?
         }
         return itemcsid;
     }
@@ -309,7 +311,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
      * Resource. They then call this method on that resource.
      */
     @Override
-       public DocumentModel getDocModelForAuthorityItem(RefName.AuthorityItem item) 
+       public DocumentModel getDocModelForAuthorityItem(RepositoryInstance repoSession, RefName.AuthorityItem item) 
                        throws Exception, DocumentNotFoundException {
        if(item == null) {
                return null;
@@ -318,11 +320,13 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         // Ensure we have the right context.
         ServiceContext ctx = createServiceContext(item.inAuthority.resource);
         
-        String parentcsid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
+        // HACK - this really must be moved to the doc handler, not here. No Nuxeo specific stuff here!
+        RepositoryJavaClientImpl client = (RepositoryJavaClientImpl)getRepositoryClient(ctx);
+        String parentcsid = client.findDocCSID(repoSession, ctx, whereClause);
 
         String itemWhereClause = buildWhereForAuthItemByName(item.getShortIdentifier(), parentcsid);
         ctx = createServiceContext(getItemServiceName());
-        DocumentWrapper<DocumentModel> docWrapper = getRepositoryClient(ctx).findDoc(ctx, itemWhereClause);
+        DocumentWrapper<DocumentModel> docWrapper = client.findDoc(repoSession, ctx, itemWhereClause);
         DocumentModel docModel = docWrapper.getWrappedObject();
         return docModel;
     }
@@ -462,7 +466,7 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
                 csid = spec.value;
             } else {
                 String whereClause = buildWhereForAuthByName(spec.value);
-                csid = getRepositoryClient(ctx).findDocCSID(ctx, whereClause);
+                csid = getRepositoryClient(ctx).findDocCSID(null, ctx, whereClause);
             }
             getRepositoryClient(ctx).update(ctx, csid, handler);
             result = ctx.getOutput();
@@ -739,30 +743,21 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(getItemServiceName(), queryParams);
             String itemcsid = lookupItemCSID(itemspecifier, parentcsid, "getReferencingObjects(item)", "GET_ITEM_REF_OBJS", ctx);
 
-            // Note that we have to create the service context for the Items, not the main service
-            // We omit the parentShortId, only needed when doing a create...
-            DocumentHandler handler = createItemDocumentHandler(ctx, parentcsid, null);
-            RepositoryClient repoClient = getRepositoryClient(ctx);
-            DocumentFilter myFilter = handler.getDocumentFilter();
             String serviceType = ServiceBindingUtils.SERVICE_TYPE_PROCEDURE;
             List<String> list = queryParams.remove(ServiceBindingUtils.SERVICE_TYPE_PROP);
             if (list != null) {
                 serviceType = list.get(0);
             }
-            DocumentWrapper<DocumentModel> docWrapper = repoClient.getDoc(ctx, itemcsid);
-            DocumentModel docModel = docWrapper.getWrappedObject();
-            String refName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
-
             // Could be smarter about using the list from above, and/or allowing multiple
             ArrayList<String> serviceTypes = new ArrayList<String>(1);
             serviceTypes.add(serviceType);
             
-            authRefDocList = RefNameServiceUtils.getAuthorityRefDocs(ctx,
-                    repoClient,
-                    serviceTypes,
-                    refName,
-                    getRefPropName(),
-                    myFilter.getPageSize(), myFilter.getStartPage(), true /*computeTotal*/);
+            // Note that we have to create the service context for the Items, not the main service
+            // We omit the parentShortId, only needed when doing a create...
+            AuthorityItemDocumentModelHandler<?> handler = (AuthorityItemDocumentModelHandler<?>)
+                                                                                               createItemDocumentHandler(ctx, parentcsid, null);
+
+            authRefDocList = handler.getReferencingObjects(ctx, serviceTypes, getRefPropName(), itemcsid);
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.GET_FAILED);
         }
index 8fdf55360fb7d9d81c1663e7588bc86306a1045d..2b449d65109fe3f348d89a1244aa10fd63a12744 100644 (file)
@@ -29,13 +29,17 @@ import org.collectionspace.services.client.PayloadOutputPart;
 import org.collectionspace.services.client.PoxPayloadIn;
 import org.collectionspace.services.client.PoxPayloadOut;
 import org.collectionspace.services.client.RelationClient;
+import org.collectionspace.services.common.ResourceBase;
+import org.collectionspace.services.common.ServiceMessages;
 import org.collectionspace.services.common.api.CommonAPI;
 import org.collectionspace.services.common.api.RefName;
 import org.collectionspace.services.common.api.Tools;
+import org.collectionspace.services.common.authorityref.AuthorityRefDocList;
 import org.collectionspace.services.common.context.MultipartServiceContext;
 import org.collectionspace.services.common.context.ServiceBindingUtils;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentFilter;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.DocumentWrapperImpl;
 import org.collectionspace.services.common.relation.IRelationsManager;
@@ -46,6 +50,7 @@ import org.collectionspace.services.common.vocabulary.AuthorityJAXBSchema;
 import org.collectionspace.services.common.vocabulary.AuthorityItemJAXBSchema;
 import org.collectionspace.services.common.vocabulary.RefNameServiceUtils;
 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
 import org.collectionspace.services.common.service.ListResultField;
 import org.collectionspace.services.nuxeo.util.NuxeoUtils;
 import org.collectionspace.services.relation.RelationResource;
@@ -54,11 +59,17 @@ import org.collectionspace.services.relation.RelationsCommonList;
 import org.collectionspace.services.relation.RelationsDocListItem;
 import org.collectionspace.services.relation.RelationshipType;
 import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.model.PropertyException;
 import org.nuxeo.ecm.core.api.model.PropertyNotFoundException;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.ws.rs.PathParam;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriInfo;
 import java.util.ArrayList;
 import java.util.List;
@@ -334,6 +345,60 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         docModel.setProperty(authorityItemCommonSchemaName,
                 AuthorityItemJAXBSchema.IN_AUTHORITY, inAuthority);
     }
+    
+    
+    public AuthorityRefDocList getReferencingObjects(
+               ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
+               ArrayList<String> serviceTypes,
+               String propertyName,
+            String itemcsid) throws Exception {
+        AuthorityRefDocList authRefDocList = null;
+       RepositoryInstance repoSession = null;
+       boolean releaseRepoSession = false;
+        
+       try { 
+               RepositoryJavaClientImpl repoClient = (RepositoryJavaClientImpl)this.getRepositoryClient(ctx);
+               repoSession = this.getRepositorySession();
+               if (repoSession == null) {
+                       repoSession = repoClient.getRepositorySession();
+                       releaseRepoSession = true;
+               }
+            DocumentFilter myFilter = getDocumentFilter();
+
+               try {
+                       DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, itemcsid);
+                       DocumentModel docModel = wrapper.getWrappedObject();
+                       String refName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
+                authRefDocList = RefNameServiceUtils.getAuthorityRefDocs(
+                               repoSession, ctx, repoClient,
+                        serviceTypes,
+                        refName,
+                        propertyName,
+                        myFilter.getPageSize(), myFilter.getStartPage(), true /*computeTotal*/);
+               } catch (PropertyException pe) {
+                       throw pe;
+               } catch (DocumentException de) {
+                       throw de;
+               } catch (Exception e) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Caught exception ", e);
+                       }
+                       throw new DocumentException(e);
+               } finally {
+                       if (releaseRepoSession && repoSession != null) {
+                               repoClient.releaseRepositorySession(repoSession);
+                       }
+               }
+       } catch (Exception e) {
+               if (logger.isDebugEnabled()) {
+                       logger.debug("Caught exception ", e);
+               }
+               throw new DocumentException(e);
+       }               
+        return authRefDocList;
+    }
+
+
 
 
     /* (non-Javadoc)
@@ -432,6 +497,11 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         RelationsCommonList childrenListOuter = getRelations(null, thisCSID, predicate);
         List<RelationsCommonList.RelationListItem> childrenList = childrenListOuter.getRelationListItem();
 
+        if(logger.isTraceEnabled()) {
+            String dump = dumpLists(thisCSID, parentList, childrenList, null);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showRelations ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
+        
         //Assume that there are more children than parents.  Will be true for parent/child, but maybe not for other relations.
         //Now add all parents to our childrenList, to be able to return just one list of consolidated results.
         //Not optimal, but that's the current design spec.
@@ -478,6 +548,10 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         long siblingSize = siblingList.size();
         siblingListOuter.setTotalItems(siblingSize);
         siblingListOuter.setItemsInPage(siblingSize);
+        if(logger.isTraceEnabled()) {
+            String dump = dumpList(siblingList, "Siblings of: "+thisCSID);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showSiblings ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
 
         PayloadOutputPart relationsPart = new PayloadOutputPart(RelationClient.SERVICE_COMMON_LIST_NAME, siblingListOuter);
         ctx.addOutputPart(relationsPart);
@@ -492,6 +566,10 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         RelationsCommonList objectListOuter = getRelations(null, thisCSID, null);   //  nulls are wildcards:  subject=*, and predicate=*
         List<RelationsCommonList.RelationListItem> objectList = objectListOuter.getRelationListItem();
 
+        if(logger.isTraceEnabled()) {
+            String dump = dumpLists(thisCSID, subjectList, objectList, null);
+            logger.trace("~~~~~~~~~~~~~~~~~~~~~~ showAllRelations ~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
+        }
         //  MERGE LISTS:
         subjectList.addAll(objectList);
 
@@ -587,6 +665,7 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         List<RelationsCommonList.RelationListItem> childList = null;
         List<RelationsCommonList.RelationListItem> parentList = null;
         DocumentModel docModel = wrapDoc.getWrappedObject();
+               String itemRefName = (String) docModel.getPropertyValue(AuthorityItemJAXBSchema.REF_NAME);
 
         ServiceContext ctx = getServiceContext();
         //Do magic replacement of ${itemCSID} and fix URI's.
@@ -629,36 +708,63 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         for (RelationsCommonList.RelationListItem inboundItem : inboundList) {
             // Note that the relations may specify the other (non-item) bit with a refName, not a CSID,
             // and so the CSID for those may be null
-            if (itemCSID.equals(inboundItem.getObject().getCsid())
-                    && inboundItem.getPredicate().equals(HAS_BROADER)) {
-                //then this is an item that says we have a child.  That child is inboundItem
-                RelationsCommonList.RelationListItem childItem =
-                        (childList == null) ? null : findInList(childList, inboundItem);
-                if (childItem != null) {
-                    removeFromList(childList, childItem);    //exists, just take it off delete list
-                } else {
-                    actionList.add(inboundItem);   //doesn't exist as a child, but is a child.  Add to additions list
-                }
-                ensureChildHasNoOtherParents(ctx, queryParams, inboundItem.getSubject().getCsid());
-
-            } else if (itemCSID.equals(inboundItem.getSubject().getCsid())
-                    && inboundItem.getPredicate().equals(HAS_BROADER)) {
-                //then this is an item that says we have a parent.  inboundItem is that parent.
-                RelationsCommonList.RelationListItem parentItem =
-                        (parentList == null) ? null : findInList(parentList, inboundItem);
-                if (parentItem != null) {
-                    removeFromList(parentList, parentItem);    //exists, just take it off delete list
+            if(inboundItem.getPredicate().equals(HAS_BROADER)) {
+               // Look for parents and children
+               if(itemCSID.equals(inboundItem.getObject().getCsid())
+                               || itemRefName.equals(inboundItem.getObject().getRefName())) {
+                       //then this is an item that says we have a child.  That child is inboundItem
+                       RelationsCommonList.RelationListItem childItem =
+                                       (childList == null) ? null : findInList(childList, inboundItem);
+                       if (childItem != null) {
+                        if (logger.isTraceEnabled()) {
+                               StringBuilder sb = new StringBuilder();
+                               itemToString(sb, "== Child: ", childItem);
+                            logger.trace("Found inboundChild in current child list: " + sb.toString());
+                        }
+                               removeFromList(childList, childItem);    //exists, just take it off delete list
+                       } else {
+                        if (logger.isTraceEnabled()) {
+                               StringBuilder sb = new StringBuilder();
+                               itemToString(sb, "== Child: ", inboundItem);
+                            logger.trace("inboundChild not in current child list, will add: " + sb.toString());
+                        }
+                               actionList.add(inboundItem);   //doesn't exist as a child, but is a child.  Add to additions list
+                               String newChildCsid = inboundItem.getSubject().getCsid();
+                               if(newChildCsid == null) {
+                                       String newChildRefName = inboundItem.getSubject().getRefName();
+                                       if(newChildRefName==null) {
+                                               throw new RuntimeException("Child with no CSID or refName!");
+                                       }
+                            if (logger.isTraceEnabled()) {
+                               logger.trace("Fetching CSID for child with only refname: "+newChildRefName);
+                            }
+                               DocumentModel newChildDocModel = 
+                                       ResourceBase.getDocModelForRefName(this.getRepositorySession(), 
+                                                       newChildRefName, getServiceContext().getResourceMap());
+                               newChildCsid = getCsid(newChildDocModel);
+                               }
+                               ensureChildHasNoOtherParents(ctx, queryParams, newChildCsid);
+                       }
+
+               } else if (itemCSID.equals(inboundItem.getSubject().getCsid())
+                                       || itemRefName.equals(inboundItem.getSubject().getRefName())) {
+                       //then this is an item that says we have a parent.  inboundItem is that parent.
+                       RelationsCommonList.RelationListItem parentItem =
+                                       (parentList == null) ? null : findInList(parentList, inboundItem);
+                       if (parentItem != null) {
+                               removeFromList(parentList, parentItem);    //exists, just take it off delete list
+                       } else {
+                               actionList.add(inboundItem);   //doesn't exist as a parent, but is a parent. Add to additions list
+                       }
                 } else {
-                    actionList.add(inboundItem);   //doesn't exist as a parent, but is a parent. Add to additions list
-                }
+                    logger.error("Parent/Child Element didn't link to this item. inboundItem: " + inboundItem);
+               }
             } else {
-                logger.warn("Element didn't match parent or child, but may have partial fields that match. inboundItem: " + inboundItem);
-                //not dealing with: hasNarrower or any other predicate.
+                logger.warn("Non-parent relation ignored. inboundItem: " + inboundItem);
             }
         }
         if (logger.isTraceEnabled()) {
             String dump = dumpLists(itemCSID, parentList, childList, actionList);
-            //System.out.println("====dump====="+CR+dump);
             logger.trace("~~~~~~~~~~~~~~~~~~~~~~dump~~~~~~~~~~~~~~~~~~~~~~~~" + CR + dump);
         }
         if (fUpdate) {
@@ -683,6 +789,7 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
     }
 
     private void ensureChildHasNoOtherParents(ServiceContext ctx, MultivaluedMap queryParams, String childCSID) {
+        logger.trace("ensureChildHasNoOtherParents for: " + childCSID );
         queryParams.putSingle(IRelationsManager.SUBJECT_QP, childCSID);
         queryParams.putSingle(IRelationsManager.PREDICATE_QP, RelationshipType.HAS_BROADER.value());
         queryParams.putSingle(IRelationsManager.OBJECT_QP, null);  //null means ANY
@@ -692,36 +799,48 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         deleteRelations(parentList, ctx, "parentList-delete");
     }
 
+    
+    private void itemToString(StringBuilder sb, String prefix, RelationsCommonList.RelationListItem item ) {
+       sb.append(prefix);
+               sb.append((item.getCsid()!= null)?item.getCsid():"NO CSID");
+       sb.append(": ["); 
+       sb.append((item.getSubject().getCsid()!=null)?item.getSubject().getCsid():item.getSubject().getRefName());
+       sb.append("]--");
+       sb.append(item.getPredicate());
+       sb.append("-->["); 
+       sb.append((item.getObject().getCsid()!=null)?item.getObject().getCsid():item.getObject().getRefName());
+       sb.append("]");
+    }
+    
     private String dumpLists(String itemCSID,
             List<RelationsCommonList.RelationListItem> parentList,
             List<RelationsCommonList.RelationListItem> childList,
             List<RelationsCommonList.RelationListItem> actionList) {
-        StringBuffer sb = new StringBuffer();
+       StringBuilder sb = new StringBuilder();
         sb.append("itemCSID: " + itemCSID + CR);
-        sb.append(dumpList(parentList, "parentList"));
-        sb.append(dumpList(childList, "childList"));
-        sb.append(dumpList(actionList, "actionList"));
+        if(parentList!=null) {
+               sb.append(dumpList(parentList, "parentList"));
+        }
+        if(childList!=null) {
+               sb.append(dumpList(childList, "childList"));
+        }
+        if(actionList!=null) {
+               sb.append(dumpList(actionList, "actionList"));
+        }
         return sb.toString();
     }
     private final static String CR = "\r\n";
     private final static String T = " ";
 
     private String dumpList(List<RelationsCommonList.RelationListItem> list, String label) {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         String s;
         if (list.size() > 0) {
             sb.append("=========== " + label + " ==========" + CR);
         }
         for (RelationsCommonList.RelationListItem item : list) {
-            s =
-                    T + item.getSubject().getCsid() //+T4 + item.getSubject().getUri()
-                    + T + item.getPredicate()
-                    + T + item.getObject().getCsid() //+T4  + item.getObject().getUri()
-                    + CR //+"subject:{"+item.getSubject()+"}\r\n object:{"+item.getObject()+"}"
-                    //+ CR + "relation-record: {"+item+"}"
-                    ;
-            sb.append(s);
-
+               itemToString(sb, "==  ", item);
+               sb.append(CR);
         }
         return sb.toString();
     }
@@ -820,10 +939,13 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
 
     private void deleteRelations(List<RelationsCommonList.RelationListItem> list, ServiceContext ctx, String listName) {
         try {
-            //if (list.size()>0){ logger.info("==== deleteRelations from : "+listName); }
             for (RelationsCommonList.RelationListItem item : list) {
                 RelationResource relationResource = new RelationResource();
-                //logger.info("==== TO DELETE: " + item.getCsid() + ": " + item.getSubject().getCsid() + "--" + item.getPredicate() + "-->" + item.getObject().getCsid());
+                if(logger.isTraceEnabled()) {
+                       StringBuilder sb = new StringBuilder();
+                       itemToString(sb, "==== TO DELETE: ", item);
+                       logger.trace(sb.toString());
+                }
                 Object res = relationResource.delete(item.getCsid());
             }
         } catch (Throwable t) {
@@ -845,30 +967,51 @@ public abstract class AuthorityItemDocumentModelHandler<AICommon>
         return result;
     }
 
-    private RelationsCommonList.RelationListItem findInList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item) {
+    // Note that the item argument may be sparse (only refName, no CSID for subject or object)
+    // But the list items must not be sparse
+    private RelationsCommonList.RelationListItem findInList(
+               List<RelationsCommonList.RelationListItem> list, 
+               RelationsCommonList.RelationListItem item) {
+       RelationsCommonList.RelationListItem foundItem = null;
         for (RelationsCommonList.RelationListItem listItem : list) {
             if (itemsEqual(listItem, item)) {   //equals must be defined, else
-                return listItem;
+               foundItem = listItem;
+               break;
             }
         }
-        return null;
+        return foundItem;
     }
 
-    private boolean itemsEqual(RelationsCommonList.RelationListItem item, RelationsCommonList.RelationListItem item2) {
-        if (item == null || item2 == null) {
+    // Note that item2 may be sparse (only refName, no CSID for subject or object)
+    // But item1 must not be sparse 
+    private boolean itemsEqual(RelationsCommonList.RelationListItem item1, RelationsCommonList.RelationListItem item2) {
+        if (item1 == null || item2 == null) {
             return false;
         }
-        RelationsDocListItem subj1 = item.getSubject();
+        RelationsDocListItem subj1 = item1.getSubject();
         RelationsDocListItem subj2 = item2.getSubject();
-        RelationsDocListItem obj1 = item.getObject();
+        RelationsDocListItem obj1 = item1.getObject();
         RelationsDocListItem obj2 = item2.getObject();
-
-        return (subj1.getCsid().equals(subj2.getCsid()))
-                && (obj1.getCsid().equals(obj1.getCsid()))
-                && ((item.getPredicate().equals(item2.getPredicate()))
-                && (item.getRelationshipType().equals(item2.getRelationshipType())))
-                && (obj1.getDocumentType().equals(obj2.getDocumentType()))
-                && (subj1.getDocumentType().equals(subj2.getDocumentType()));
+        String subj1Csid = subj1.getCsid();
+        String subj2Csid = subj2.getCsid();
+        String subj1RefName = subj1.getRefName();
+        String subj2RefName = subj2.getRefName();
+
+        String obj1Csid = obj1.getCsid();
+        String obj2Csid = obj2.getCsid();
+        String obj1RefName = obj1.getRefName();
+        String obj2RefName = obj2.getRefName();
+
+        boolean isEqual = 
+                          (subj1Csid.equals(subj2Csid) || ((subj2Csid==null)  && subj1RefName.equals(subj2RefName)))
+                && (obj1Csid.equals(obj1Csid)   || ((obj2Csid==null)   && obj1RefName.equals(obj2RefName)))
+                // predicate is proper, but still allow relationshipType
+                && (item1.getPredicate().equals(item2.getPredicate())
+                       ||  ((item2.getPredicate()==null)  && item1.getRelationshipType().equals(item2.getRelationshipType())))
+                // Allow missing docTypes, so long as they do not conflict
+                && (obj1.getDocumentType().equals(obj2.getDocumentType()) || obj2.getDocumentType()==null)
+                && (subj1.getDocumentType().equals(subj2.getDocumentType()) || subj2.getDocumentType()==null);
+        return isEqual;
     }
 
     private void removeFromList(List<RelationsCommonList.RelationListItem> list, RelationsCommonList.RelationListItem item) {
index cc9e01425a946e33887d0a6354de97178ab26b07..b064cb1471155f3ebe3f9012de12b5cd4aee56c2 100644 (file)
@@ -27,6 +27,7 @@ import java.util.List;
 
 import org.collectionspace.services.BatchJAXBSchema;
 import org.collectionspace.services.jaxb.InvocableJAXBSchema;
+import org.collectionspace.services.batch.nuxeo.BatchDocumentModelHandler;
 import org.collectionspace.services.client.BatchClient;
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.PoxPayloadIn;
@@ -70,8 +71,6 @@ import javax.ws.rs.core.UriInfo;
 @Consumes({"application/xml"})
 public class BatchResource extends ResourceBase {
        
-       protected final int BAD_REQUEST_STATUS = Response.Status.BAD_REQUEST.getStatusCode();
-       
        protected final String COMMON_SCHEMA = "batch_common";
 
     @Override
@@ -186,89 +185,9 @@ public class BatchResource extends ResourceBase {
                InvocationContext invContext) {
         try {
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
-            DocumentHandler handler = createDocumentHandler(ctx);
-            DocumentWrapper<DocumentModel> wrapper = 
-               getRepositoryClient(ctx).getDoc(ctx, csid);
-               DocumentModel docModel = wrapper.getWrappedObject();
-               String invocationMode = invContext.getMode();
-               String modeProperty = null;
-               boolean checkDocType = true;
-               if(BatchInvocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = BatchJAXBSchema.SUPPORTS_SINGLE_DOC;
-               } else if(BatchInvocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = BatchJAXBSchema.SUPPORTS_DOC_LIST;
-               } else if(BatchInvocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = BatchJAXBSchema.SUPPORTS_GROUP;
-               } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;
-                       checkDocType = false;
-               } else {
-                       throw new BadRequestException("BatchResource: unknown Invocation Mode: "
-                               +invocationMode);
-               }
-               Boolean supports = (Boolean)docModel.getPropertyValue(modeProperty);
-               if(!supports) {
-                       throw new BadRequestException("BatchResource: This Batch Job does not support Invocation Mode: "
-                               +invocationMode);
-               }
-               String className = 
-                       (String)docModel.getPropertyValue(BatchJAXBSchema.BATCH_CLASS_NAME);
-               className = className.trim();
-            ClassLoader tccl = Thread.currentThread().getContextClassLoader();
-            Class<?> c = tccl.loadClass(className);
-               // enable validation assertions
-               tccl.setClassAssertionStatus(className, true);
-            if(!BatchInvocable.class.isAssignableFrom(c)) {
-               throw new RuntimeException("BatchResource: Class: "
-                               +className+" does not implement BatchInvocable!");
-            } else {
-               BatchInvocable batchInstance = (BatchInvocable)c.newInstance();
-               List<String> modes = batchInstance.getSupportedInvocationModes();
-               if(!modes.contains(invocationMode)) {
-                       throw new BadRequestException(
-                                       "BatchResource: Invoked with unsupported context mode: "
-                                       +invocationMode);
-               }
-               if(checkDocType) {
-                               List<String> forDocTypeList = 
-                                       (List<String>)docModel.getPropertyValue(BatchJAXBSchema.FOR_DOC_TYPES);
-                               if(forDocTypeList==null
-                                       || !forDocTypeList.contains(invContext.getDocType())) {
-                               throw new BadRequestException(
-                                               "BatchResource: Invoked with unsupported document type: "
-                                               +invContext.getDocType());
-                       }
-               }
-               batchInstance.setInvocationContext(invContext);
-               //ResourceMapHolder csapp = (ResourceMapHolder)app;
-               if(resourceMap!=null) {
-                       batchInstance.setResourceMap(resourceMap);
-               } else {
-                       resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
-                       if(resourceMap!=null) {
-                               batchInstance.setResourceMap(resourceMap);
-                       } else {
-                               logger.warn("BatchResource.invoke did not get a resourceMapHolder in Context!");
-                       }
-               }
-               batchInstance.run();
-               int status = batchInstance.getCompletionStatus();
-               if(status == Invocable.STATUS_ERROR) {
-                       InvocationError error = batchInstance.getErrorInfo();
-                       if(error.getResponseCode() == BAD_REQUEST_STATUS) {
-                               throw new BadRequestException(
-                                       "BatchResouce: batchProcess encountered error: "
-                                       +batchInstance.getErrorInfo());
-                       } else {
-                               throw new RuntimeException(
-                                               "BatchResouce: batchProcess encountered error: "
-                                               +batchInstance.getErrorInfo());
-
-                       }
-               }
-               InvocationResults results = batchInstance.getResults();
-               return results;
-            }
+            BatchDocumentModelHandler handler = (BatchDocumentModelHandler)createDocumentHandler(ctx);
+            
+            return handler.invokeBatchJob(ctx, csid, resourceMap, invContext);
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.POST_FAILED);
         }
index a5fe3e0c4b987811f4c2ed5cffe5127671b8a296..4777d291f5b9b1073350c45797c2f1d16b10029b 100644 (file)
  */
 package org.collectionspace.services.batch.nuxeo;
 
+import java.util.List;
+
+import javax.ws.rs.PathParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.Response;
+
+import org.collectionspace.services.BatchJAXBSchema;
+import org.collectionspace.services.jaxb.InvocableJAXBSchema;
 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
 import org.collectionspace.services.batch.BatchCommon;
+import org.collectionspace.services.batch.BatchInvocable;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.ServiceMessages;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentFilter;
+import org.collectionspace.services.common.document.DocumentHandler;
+import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.invocable.Invocable;
+import org.collectionspace.services.common.invocable.InvocationContext;
+import org.collectionspace.services.common.invocable.InvocationResults;
+import org.collectionspace.services.common.invocable.Invocable.InvocationError;
+import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.model.PropertyException;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class BatchDocumentModelHandler 
        extends DocHandlerBase<BatchCommon> {
+    private final Logger logger = LoggerFactory.getLogger(BatchDocumentModelHandler.class);
+
+       protected final int BAD_REQUEST_STATUS = Response.Status.BAD_REQUEST.getStatusCode();
+       
+       public InvocationResults invokeBatchJob(
+                       ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
+                       String csid,
+                       ResourceMap resourceMap, 
+                       InvocationContext invContext) throws Exception {
+
+               RepositoryInstance repoSession = null;
+               boolean releaseRepoSession = false;
+
+               String invocationMode = invContext.getMode();
+               String modeProperty = null;
+               boolean checkDocType = true;
+               if(BatchInvocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = BatchJAXBSchema.SUPPORTS_SINGLE_DOC;
+               } else if(BatchInvocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = BatchJAXBSchema.SUPPORTS_DOC_LIST;
+               } else if(BatchInvocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = BatchJAXBSchema.SUPPORTS_GROUP;
+               } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;
+                       checkDocType = false;
+               } else {
+                       throw new BadRequestException("BatchResource: unknown Invocation Mode: "
+                                       +invocationMode);
+               }
+
+               RepositoryJavaClientImpl repoClient = (RepositoryJavaClientImpl)this.getRepositoryClient(ctx);
+               repoSession = this.getRepositorySession();
+               if (repoSession == null) {
+                       repoSession = repoClient.getRepositorySession();
+                       releaseRepoSession = true;
+               }
+
+               String className = null;
+               // Get properties from the batch docModel, and release the session
+               try {
+                       DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, csid);
+                       DocumentModel docModel = wrapper.getWrappedObject();
+                       Boolean supports = (Boolean)docModel.getPropertyValue(modeProperty);
+                       if(!supports) {
+                               throw new BadRequestException("BatchResource: This Batch Job does not support Invocation Mode: "
+                                               +invocationMode);
+                       }
+                       if(checkDocType) {
+                               List<String> forDocTypeList = 
+                                               (List<String>)docModel.getPropertyValue(BatchJAXBSchema.FOR_DOC_TYPES);
+                               if(forDocTypeList==null
+                                               || !forDocTypeList.contains(invContext.getDocType())) {
+                                       throw new BadRequestException(
+                                                       "BatchResource: Invoked with unsupported document type: "
+                                                                       +invContext.getDocType());
+                               }
+                       }
+                       className = (String)docModel.getPropertyValue(BatchJAXBSchema.BATCH_CLASS_NAME);
+               } catch (PropertyException pe) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Property exception getting batch values: ", pe);
+                       }
+                       throw pe;
+               } catch (DocumentException de) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Problem getting batch doc: ", de);
+                       }
+                       throw de;
+               } catch (Exception e) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Caught exception ", e);
+                       }
+                       throw new DocumentException(e);
+               } finally {
+                       if (releaseRepoSession && repoSession != null) {
+                               repoClient.releaseRepositorySession(repoSession);
+                       }
+               }
+               className = className.trim();
+               ClassLoader tccl = Thread.currentThread().getContextClassLoader();
+               Class<?> c = tccl.loadClass(className);
+               // enable validation assertions
+               tccl.setClassAssertionStatus(className, true);
+               if(!BatchInvocable.class.isAssignableFrom(c)) {
+                       throw new RuntimeException("BatchResource: Class: "
+                                       +className+" does not implement BatchInvocable!");
+               }
+               BatchInvocable batchInstance = (BatchInvocable)c.newInstance();
+               List<String> modes = batchInstance.getSupportedInvocationModes();
+               if(!modes.contains(invocationMode)) {
+                       throw new BadRequestException(
+                                       "BatchResource: Invoked with unsupported context mode: "
+                                                       +invocationMode);
+               }
+               batchInstance.setInvocationContext(invContext);
+               if(resourceMap!=null) {
+                       batchInstance.setResourceMap(resourceMap);
+               } else {
+                       resourceMap = ResteasyProviderFactory.getContextData(ResourceMap.class);
+                       if(resourceMap!=null) {
+                               batchInstance.setResourceMap(resourceMap);
+                       } else {
+                               logger.warn("BatchResource.invoke did not get a resourceMapHolder in Context!");
+                       }
+               }
+               batchInstance.run();
+               int status = batchInstance.getCompletionStatus();
+               if(status == Invocable.STATUS_ERROR) {
+                       InvocationError error = batchInstance.getErrorInfo();
+                       if(error.getResponseCode() == BAD_REQUEST_STATUS) {
+                               throw new BadRequestException(
+                                               "BatchResouce: batchProcess encountered error: "
+                                                               +batchInstance.getErrorInfo());
+                       } else {
+                               throw new RuntimeException(
+                                               "BatchResouce: batchProcess encountered error: "
+                                                               +batchInstance.getErrorInfo());
+
+                       }
+               }
+               InvocationResults results = batchInstance.getResults();
+               return results;
+       }
 }
 
index 5cb29bf8b30c22af0e64e5371d5d45312f25525d..3f2d2896cdfdbdb87a100842f3f578e06a97d3bd 100644 (file)
@@ -46,6 +46,7 @@ import org.jboss.resteasy.plugins.providers.multipart.MultipartInput;
 import org.jboss.resteasy.plugins.providers.multipart.MultipartOutput;\r
 import org.jboss.resteasy.util.HttpResponseCodes;\r
 import org.nuxeo.ecm.core.api.DocumentModel;\r
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
 \r
 import javax.ws.rs.*;\r
 import javax.ws.rs.core.*;\r
@@ -357,7 +358,7 @@ public abstract class ResourceBase
      * for all inheriting resource classes. Just use ServiceContext.getResourceMap() to get\r
      * the map, and pass it in.\r
      */\r
-    public static DocumentModel getDocModelForRefName(String refName, ResourceMap resourceMap) \r
+    public static DocumentModel getDocModelForRefName(RepositoryInstance repoSession, String refName, ResourceMap resourceMap) \r
                        throws Exception, DocumentNotFoundException {\r
        // TODO - we need to generalize the idea of a refName to more than Authorities and Items. \r
        RefName.AuthorityItem item = RefName.AuthorityItem.parse(refName);\r
@@ -365,20 +366,20 @@ public abstract class ResourceBase
                return null;\r
        }\r
        ResourceBase resource = resourceMap.get(item.inAuthority.resource);\r
-       return resource.getDocModelForAuthorityItem(item);\r
+       return resource.getDocModelForAuthorityItem(repoSession, item);\r
     }\r
 \r
     // THis is ugly, but prevents us parsing the refName twice. Once we make refName a little more\r
     // general, and less Authority(Item) specific, this will look better.\r
-       public DocumentModel getDocModelForAuthorityItem(RefName.AuthorityItem item) \r
+       public DocumentModel getDocModelForAuthorityItem(RepositoryInstance repoSession, RefName.AuthorityItem item) \r
                        throws Exception, DocumentNotFoundException {\r
                logger.warn("Default (ResourceBase) getDocModelForAuthorityItem called - should not happen!");\r
                return null;\r
        }\r
 \r
-    public DocumentModel getDocModelForRefName(String refName) \r
+    public DocumentModel getDocModelForRefName(RepositoryInstance repoSession, String refName) \r
                        throws Exception, DocumentNotFoundException {\r
-       return getDocModelForAuthorityItem(RefName.AuthorityItem.parse(refName));\r
+       return getDocModelForAuthorityItem(repoSession, RefName.AuthorityItem.parse(refName));\r
     }\r
 \r
 }\r
index 43acb2113d3513bdb1d10b2257a283d459db7e9b..c3d815a8e3f94cd77014cdc796393322f7786e40 100644 (file)
@@ -34,6 +34,7 @@ import org.collectionspace.services.common.storage.StorageClient;
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.DocumentModel;
 import org.nuxeo.ecm.core.api.DocumentModelList;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
 
 /**
  * RepositoryClient is a generic Document Repository client
@@ -96,6 +97,7 @@ public interface RepositoryClient<IT, OT> extends StorageClient {
      *            of the document to retrieve
      * @throws DocumentException
      */
+    @Deprecated
     public DocumentWrapper<DocumentModel> getDoc(
             ServiceContext<IT, OT> ctx, String id)
             throws DocumentNotFoundException, DocumentException;
@@ -124,7 +126,7 @@ public interface RepositoryClient<IT, OT> extends StorageClient {
      * @param where NXQL where clause to get the document
      * @throws DocumentException
      */
-    public String findDocCSID(
+    public String findDocCSID(RepositoryInstance repoSession, 
             ServiceContext<IT, OT> ctx, String where)
             throws DocumentNotFoundException, DocumentException;
 
index 15b8c8c6072813ba1a7cfbf74767eab35f89c132..2c2148e7041ea44c0520a6c208d38977e470c0f9 100644 (file)
@@ -92,10 +92,16 @@ public class SecurityInterceptor implements PreProcessInterceptor, PostProcessIn
        @Override
        public ServerResponse preProcess(HttpRequest request, ResourceMethod method)
        throws Failure, WebApplicationException {
+               final String servicesResource = "/cspace-services/"; // HACK - this is configured in war
+               final int servicesResourceLen = servicesResource.length();
                String httpMethod = request.getHttpMethod();
                String uriPath = request.getUri().getPath();
                if (logger.isDebugEnabled()) {
-                       logger.debug("received " + httpMethod + " on " + uriPath);
+                       String fullRequest = request.getUri().getRequestUri().toString();
+                       int servicesResourceIdx = fullRequest.indexOf(servicesResource);
+                       String relativeRequest = (servicesResourceIdx<=0)? fullRequest
+                                                                                               :fullRequest.substring(servicesResourceIdx+servicesResourceLen);
+                       logger.debug("received " + httpMethod + " on " + relativeRequest);
                }
                String resName = SecurityUtils.getResourceName(request.getUri());
                String resEntity = SecurityUtils.getResourceEntity(resName);
index 4841eb4d6799c77a3e6831cb417d7d23e35c4ba6..ab2efb03c1aac1aad06a25f326ae10087a94a472 100644 (file)
@@ -204,6 +204,7 @@ public class RefNameServiceUtils {
     }\r
 \r
     public static AuthorityRefDocList getAuthorityRefDocs(\r
+               RepositoryInstance repoSession,\r
                ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,\r
             RepositoryClient<PoxPayloadIn, PoxPayloadOut> repoClient,\r
             List<String> serviceTypes,\r
@@ -222,9 +223,7 @@ public class RefNameServiceUtils {
         Map<String, List<AuthRefConfigInfo>> authRefFieldsByService = new HashMap<String, List<AuthRefConfigInfo>>();\r
 \r
         RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl)repoClient;\r
-       RepositoryInstance repoSession = null;\r
        try {\r
-               repoSession = nuxeoRepoClient.getRepositorySession();\r
                DocumentModelList docList = findAuthorityRefDocs(ctx, repoClient, repoSession,\r
                                serviceTypes, refName, refPropName, queriedServiceBindings, authRefFieldsByService, pageSize, pageNum, computeTotal);\r
        \r
@@ -244,10 +243,6 @@ public class RefNameServiceUtils {
        } catch (Exception e) {\r
                        logger.error("Could not retrieve the Nuxeo repository", e);\r
                        wrapperList = null;\r
-               } finally {\r
-               if (repoSession != null) {\r
-                       nuxeoRepoClient.releaseRepositorySession(repoSession);\r
-               }\r
        }\r
               \r
        return wrapperList;\r
@@ -353,7 +348,7 @@ public class RefNameServiceUtils {
         return docList;\r
     }\r
     \r
-    private static final boolean READY_FOR_COMPLEX_QUERY = false;\r
+    private static final boolean READY_FOR_COMPLEX_QUERY = true;\r
     \r
     private static String computeWhereClauseForAuthorityRefDocs(\r
                String escapedRefName,\r
index ca7ff53a1c533dbf712f920e5db4b89cf294fdaf..c6bcde2bde8bf8fa2384deee36d4775cfe5b1090 100644 (file)
@@ -51,6 +51,8 @@ import org.collectionspace.services.common.context.MultipartServiceContext;
 import org.collectionspace.services.common.context.ServiceContext;
 import org.collectionspace.services.common.datetime.DateTimeFormatUtils;
 import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentNotFoundException;
 import org.collectionspace.services.common.document.DocumentUtils;
 import org.collectionspace.services.common.document.DocumentWrapper;
 import org.collectionspace.services.common.document.DocumentFilter;
@@ -383,6 +385,57 @@ public abstract class   RemoteDocumentModelHandlerImpl<T, TL>
         return result;
     }
     
+    /* 
+    public String getStringPropertyFromDoc(
+               ServiceContext ctx,
+               String csid,
+               String propertyXPath ) throws DocumentNotFoundException, DocumentException {
+       RepositoryInstance repoSession = null;
+       boolean releaseRepoSession = false;
+       String returnValue = null;
+
+       try{ 
+               RepositoryJavaClientImpl repoClient = (RepositoryJavaClientImpl)this.getRepositoryClient(ctx);
+               repoSession = this.getRepositorySession();
+               if (repoSession == null) {
+                       repoSession = repoClient.getRepositorySession();
+                       releaseRepoSession = true;
+               }
+
+               try {
+                       DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, csid);
+                       DocumentModel docModel = wrapper.getWrappedObject();
+                       returnValue = (String) docModel.getPropertyValue(propertyXPath);
+               } catch (PropertyException pe) {
+                       throw pe;
+               } catch (DocumentException de) {
+                       throw de;
+               } catch (Exception e) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Caught exception ", e);
+                       }
+                       throw new DocumentException(e);
+               } finally {
+                       if (releaseRepoSession && repoSession != null) {
+                               repoClient.releaseRepositorySession(repoSession);
+                       }
+               }
+       } catch (Exception e) {
+               if (logger.isDebugEnabled()) {
+                       logger.debug("Caught exception ", e);
+               }
+               throw new DocumentException(e);
+       }               
+
+
+       if (logger.isWarnEnabled() == true) {
+               logger.warn("Returned DocumentModel instance was created with a repository session that is now closed.");
+       }
+       return returnValue;
+    }
+     */
+
+    
 
     /* (non-Javadoc)
      * @see org.collectionspace.services.nuxeo.client.java.DocumentModelHandler#getAuthorityRefs(org.collectionspace.services.common.document.DocumentWrapper, java.util.List)
index b5885b71809e3db1019c7e34aa0626470a4454b7..f94da13622f9ee98a774a21ebd778980febf30fd 100644 (file)
@@ -170,9 +170,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
         } catch (BadRequestException bre) {
             throw bre;
         } catch (Exception e) {
-            if (logger.isDebugEnabled()) {
-                logger.debug("Caught exception ", e);
-            }
+                logger.error("Caught exception ", e);
             throw new DocumentException(e);
         } finally {
             if (repoSession != null) {
@@ -356,8 +354,8 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
     }
 
     public DocumentWrapper<DocumentModel> findDoc(
-            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
             RepositoryInstance repoSession,
+            ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
             String whereClause)
             throws DocumentNotFoundException, DocumentException {
         DocumentWrapper<DocumentModel> wrapDoc = null;
@@ -411,7 +409,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
 
         try {
             repoSession = getRepositorySession();
-            wrapDoc = findDoc(ctx, repoSession, whereClause);
+            wrapDoc = findDoc(repoSession, ctx, whereClause);
         } catch (Exception e) {
                        throw new DocumentException("Unable to create a Nuxeo repository session.", e);
                } finally {
@@ -434,14 +432,17 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
      * @throws DocumentException
      */
     @Override
-    public String findDocCSID(
+    public String findDocCSID(RepositoryInstance repoSession, 
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, String whereClause)
             throws DocumentNotFoundException, DocumentException {
         String csid = null;
-        RepositoryInstance repoSession = null;
+        boolean releaseSession = false;
         try {
-               repoSession = this.getRepositorySession();
-            DocumentWrapper<DocumentModel> wrapDoc = findDoc(ctx, repoSession, whereClause);
+               if(repoSession== null) {
+                       repoSession = this.getRepositorySession();
+                       releaseSession = true;
+               }
+            DocumentWrapper<DocumentModel> wrapDoc = findDoc(repoSession, ctx, whereClause);
             DocumentModel docModel = wrapDoc.getWrappedObject();
             csid = NuxeoUtils.getCsid(docModel);//NuxeoUtils.extractId(docModel.getPathAsString());
         } catch (DocumentNotFoundException dnfe) {
@@ -456,7 +457,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             }
             throw new DocumentException(e);
         } finally {
-               if (repoSession != null) {
+               if(releaseSession && (repoSession != null)) {
                        this.releaseRepositorySession(repoSession);
                }
         }
@@ -481,6 +482,9 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
             // force limit to 1, and ignore totalSize
             QueryContext queryContext = new QueryContext(ctx, whereClause);
             String query = NuxeoUtils.buildNXQLQuery(docTypes, queryContext);
+            if (logger.isDebugEnabled()) {
+                logger.debug("findDocs() NXQL: "+query);
+            }
             docList = repoSession.query(query, null, pageSize, pageNum, computeTotal);
             wrapDoc = new DocumentWrapperImpl<DocumentModelList>(docList);
         } catch (IllegalArgumentException iae) {
@@ -953,11 +957,14 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
                     + domainDoc.getPathAsString());
             workspacesRoot = repoSession.createDocument(workspacesRoot);
             String workspacesRootId = workspacesRoot.getId();
+            repoSession.save();
             
             if (logger.isDebugEnabled()) {
                 logger.debug("Created tenant domain name=" + domainName
                         + " id=" + domainId + " " +
                         NuxeoUtils.Workspaces + " id=" + workspacesRootId);
+                logger.debug("Path to Domain: "+domainDoc.getPathAsString());
+                logger.debug("Path to Workspaces root: "+workspacesRoot.getPathAsString());
             }
         } catch (Exception e) {
             if (logger.isDebugEnabled()) {
@@ -1011,10 +1018,24 @@ public class RepositoryJavaClientImpl implements RepositoryClient<PoxPayloadIn,
         String workspaceId = null;
         try {
             repoSession = getRepositorySession();
+            String parentDocRefPath = "/" + domainName + "/" + NuxeoUtils.Workspaces;
             DocumentRef parentDocRef = new PathRef(
                     "/" + domainName
                     + "/" + NuxeoUtils.Workspaces);
-            DocumentModel parentDoc = repoSession.getDocument(parentDocRef);
+            if (logger.isDebugEnabled()) {
+                logger.debug("Fetching "+NuxeoUtils.Workspaces+", path=" + parentDocRefPath
+                        + " docRef:" + parentDocRef.toString());
+            }
+            DocumentModel parentDoc = null;
+            try {
+               parentDoc = repoSession.getDocument(parentDocRef);
+            } catch(ClientException ce) {
+                logger.error("Failed to get "+NuxeoUtils.Workspaces+", path=" + parentDocRefPath
+                        + " docRef:" + parentDocRef.toString());
+               // try again for debugging
+                parentDoc = repoSession.getDocument(parentDocRef);
+                //throw ce;
+            }
             DocumentModel doc = repoSession.createDocumentModel(parentDoc.getPathAsString(),
                     workspaceName, "Workspace");
             doc.setPropertyValue("dc:title", workspaceName);
index 120b90ef9005bb22883ae6d44c927c788dada583..e5b7e18446db450dc09eb33c6acb6814592657ea 100644 (file)
@@ -146,6 +146,12 @@ public class TenantRepository {
                 logger.debug("Created repository domain for " + domainName
                         + " id=" + domainId);
             }
+            if (logger.isTraceEnabled()) {
+                String checkDomainId = repositoryClient.getDomainId(repositoryDomain.getStorageName());
+                logger.trace("Fetched repository domain for " + domainName
+                        + " fetchedId=" + checkDomainId);
+                // Now try to fetch the workspace
+            }
         } else {
             if (logger.isDebugEnabled()) {
                 logger.debug("Found repository domain for " + domainName
@@ -192,6 +198,15 @@ public class TenantRepository {
             }
             repositoryDomainName = repositoryDomainName.trim();
             if (!repositoryDomain.getName().equalsIgnoreCase(repositoryDomainName)) {
+                if (logger.isWarnEnabled()) {
+                    logger.warn("The service " + serviceName
+                            + " for tenant=" + tenantBinding.getName()
+                            + " declares a document repository: \""
+                            + repositoryDomainName
+                            + "\" that does not match the expected domain name: \""
+                            + repositoryDomain.getStorageName()
+                            +"\"");
+                }
                 continue;
             }
             String workspaceId = null;
index bb3e18f2524c77ccaeb7ca2063f02eae13406783..dc86d531ad285b1d139da0b87b083b7e35ce01f7 100644 (file)
@@ -11,7 +11,7 @@ public class LoanoutValidatorHandler implements ValidatorHandler {
        public void validate(Action action, ServiceContext ctx)
                        throws InvalidDocumentException {
                // TODO Auto-generated method stub
-               System.out.println("LoanoutValidatorHandler executed.");
+               //System.out.println("LoanoutValidatorHandler executed.");
 
        }
 
index e6531db607806982adf6f83005000ffd202c107d..4d131ca8e5b7c9365749cbe07d897ee39c44ecdd 100644 (file)
@@ -116,8 +116,8 @@ public class RelationDocumentModelHandler
         ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
         RepositoryInstance repoSession = this.getRepositorySession();
         
-        DocumentModel subjectDocModel = getSubjectOrObjectDocModel(relationDocModel, SUBJ_DOC_MODEL);
-        DocumentModel objectDocModel = getSubjectOrObjectDocModel(relationDocModel, OBJ_DOC_MODEL);
+        DocumentModel subjectDocModel = getSubjectOrObjectDocModel(repoSession, relationDocModel, SUBJ_DOC_MODEL);
+        DocumentModel objectDocModel = getSubjectOrObjectDocModel(repoSession, relationDocModel, OBJ_DOC_MODEL);
 
         // Use values from the subject and object document models to populate the
         // relevant fields of the relation's own document model.
@@ -309,6 +309,7 @@ public class RelationDocumentModelHandler
     private final boolean OBJ_DOC_MODEL = false;
     
     private DocumentModel getSubjectOrObjectDocModel(
+               RepositoryInstance repoSession,
                DocumentModel relationDocModel,
                boolean fSubject) throws Exception {
        ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = this.getServiceContext();
@@ -331,13 +332,13 @@ public class RelationDocumentModelHandler
         }
         if (Tools.notBlank(csid)) {
                RepositoryJavaClientImpl nuxeoRepoClient = (RepositoryJavaClientImpl)getRepositoryClient(ctx);
-            DocumentWrapper<DocumentModel> docWrapper = nuxeoRepoClient.getDocFromCsid(ctx, this.getRepositorySession(), csid);
+            DocumentWrapper<DocumentModel> docWrapper = nuxeoRepoClient.getDocFromCsid(ctx, repoSession, csid);
             docModel = docWrapper.getWrappedObject();
         } else { //  if (Tools.isBlank(objectCsid)) {
             try {
                refName = (String) relationDocModel.getProperty(commonPartLabel, 
                                (fSubject?RelationJAXBSchema.SUBJECT_REFNAME:RelationJAXBSchema.OBJECT_REFNAME));
-               docModel = ResourceBase.getDocModelForRefName(refName, ctx.getResourceMap());
+               docModel = ResourceBase.getDocModelForRefName(repoSession, refName, ctx.getResourceMap());
             } catch (Exception e) {
                 throw new InvalidDocumentException(
                         "Relation record must have a CSID or refName to identify the object of the relation.", e);
index baa9137461926277ce219bef1c6047d7ddb65e94..3192d519df7929fd7f1be7a920019f41de921a36 100644 (file)
@@ -30,6 +30,7 @@ import net.sf.jasperreports.engine.JasperPrint;
 
 import org.collectionspace.services.jaxb.AbstractCommonList;
 import org.collectionspace.services.jaxb.InvocableJAXBSchema;
+import org.collectionspace.services.report.nuxeo.ReportDocumentModelHandler;
 import org.collectionspace.services.ReportJAXBSchema;
 import org.collectionspace.services.client.IQueryManager;
 import org.collectionspace.services.client.PoxPayloadIn;
@@ -188,158 +189,14 @@ public class ReportResource extends ResourceBase {
         }
         try {
             ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext();
-            DocumentHandler handler = createDocumentHandler(ctx);
-            DocumentWrapper<DocumentModel> wrapper = 
-               getRepositoryClient(ctx).getDoc(ctx, csid);
-               DocumentModel docModel = wrapper.getWrappedObject();
-               String invocationMode = invContext.getMode();
-               String modeProperty = null;
-               HashMap params = new HashMap();
-               params.put(REPORTS_STD_TENANTID_PARAM, ctx.getTenantId());
-               boolean checkDocType = true;
-               if(Invocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = InvocableJAXBSchema.SUPPORTS_SINGLE_DOC;
-                       params.put(REPORTS_STD_CSID_PARAM, invContext.getSingleCSID());
-               } else if(Invocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = InvocableJAXBSchema.SUPPORTS_DOC_LIST;
-                       List<String> csids = null;
-                       InvocationContext.ListCSIDs listThing = invContext.getListCSIDs();
-                               if(listThing!=null) {
-                                       csids = listThing.getCsid();
-                               }
-                               if(csids==null||csids.isEmpty()){
-                               throw new BadRequestException(
-                                               "ReportResource: Report invoked in list mode, with no csids in list." );
-                               }
-                               StringBuilder sb = new StringBuilder();
-                               boolean first = true;
-                               for(String csidItem : csids) {
-                                       if(first)
-                                               first = false;
-                                       else
-                                               sb.append(CSID_LIST_SEPARATOR);
-                                       sb.append(csidItem);
-                               }
-                       params.put(REPORTS_STD_CSIDLIST_PARAM, sb.toString());
-               } else if(Invocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = InvocableJAXBSchema.SUPPORTS_GROUP;
-                       params.put(REPORTS_STD_GROUPCSID_PARAM, invContext.getGroupCSID());
-               } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {
-                       modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;
-                       checkDocType = false;
-               } else {
-                       throw new BadRequestException("ReportResource: unknown Invocation Mode: "
-                               +invocationMode);
-               }
-               Boolean supports = (Boolean)docModel.getPropertyValue(modeProperty);
-               if(supports == null || !supports) {
-                       throw new BadRequestException(
-                                       "ReportResource: This Report does not support Invocation Mode: "
-                               +invocationMode);
-               }
-               if(checkDocType) {
-                       List<String> forDocTypeList = 
-                               (List<String>)docModel.getPropertyValue(InvocableJAXBSchema.FOR_DOC_TYPES);
-                       if(forDocTypeList==null
-                                       || !forDocTypeList.contains(invContext.getDocType())) {
-                       throw new BadRequestException(
-                                       "ReportResource: Invoked with unsupported document type: "
-                                       +invContext.getDocType());
-               }
-               }
-               String reportFileName = (String)docModel.getPropertyValue(ReportJAXBSchema.FILENAME);
-
-               return buildReportResponse(csid, params, reportFileName);
+            ReportDocumentModelHandler handler = (ReportDocumentModelHandler)createDocumentHandler(ctx);
+            
+            return handler.invokeReport(ctx, csid, invContext);
         } catch (Exception e) {
             throw bigReThrow(e, ServiceMessages.POST_FAILED);
         }
     }
     
-    private Response buildReportResponse(String reportCSID, HashMap params, String reportFileName) {
-               Connection conn = null;
-               Response response = null;
-       try {
-                       String fullPath = ServiceMain.getInstance().getServerRootDir() +
-                                                               File.separator + ConfigReader.CSPACE_DIR_NAME + 
-                                                               File.separator + REPORTS_FOLDER +
-                                                               // File.separator + tenantName +
-                                                               File.separator + reportFileName;
-                       conn = getConnection();
-       
-            if (logger.isTraceEnabled()) {
-               logger.trace("ReportResource for Report csid=" + reportCSID
-                               +" opening report file: "+fullPath);
-            }
-                       FileInputStream fileStream = new FileInputStream(fullPath);
-       
-               // fill the report
-                       JasperPrint jasperprint = JasperFillManager.fillReport(fileStream, params,conn);
-                       // export report to pdf and build a response with the bytes
-                       byte[] pdfasbytes = JasperExportManager.exportReportToPdf(jasperprint);
-                       
-                       // Need to set response type for what is requested...
-               response = Response.ok(pdfasbytes, "application/pdf").build();
-       
-               return response;        
-        } catch (SQLException sqle) {
-            // SQLExceptions can be chained. We have at least one exception, so
-            // set up a loop to make sure we let the user know about all of them
-            // if there happens to be more than one.
-            if (logger.isDebugEnabled()) {
-                   SQLException tempException = sqle;
-                   while (null != tempException) {
-                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
-       
-                       // loop to the next exception
-                       tempException = tempException.getNextException();
-                   }
-            }
-            response = Response.status(
-                    Response.Status.INTERNAL_SERVER_ERROR).entity(
-                               "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
-            throw new WebApplicationException(response);
-        } catch (JRException jre) {
-            if (logger.isDebugEnabled()) {
-               logger.debug("JR Exception: " + jre.getLocalizedMessage() + " Cause: "+jre.getCause());
-            }
-            response = Response.status(
-                    Response.Status.INTERNAL_SERVER_ERROR).entity(
-                               "Invoke failed (Jasper problem) on Report csid=" + reportCSID).type("text/plain").build();
-            throw new WebApplicationException(response);
-        } catch (FileNotFoundException fnfe) {
-            if (logger.isDebugEnabled()) {
-               logger.debug("FileNotFoundException: " + fnfe.getLocalizedMessage());
-            }
-            response = Response.status(
-                    Response.Status.INTERNAL_SERVER_ERROR).entity(
-                               "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
-            throw new WebApplicationException(response);
-        } catch (Exception e) {
-            throw bigReThrow(e, ServiceMessages.POST_FAILED);
-               } finally {
-               if(conn!=null) {
-                       try {
-                       conn.close();
-                } catch (SQLException sqle) {
-                    // SQLExceptions can be chained. We have at least one exception, so
-                    // set up a loop to make sure we let the user know about all of them
-                    // if there happens to be more than one.
-                    if (logger.isDebugEnabled()) {
-                               logger.debug("SQL Exception closing connection: " 
-                                               + sqle.getLocalizedMessage());
-                    }
-                } catch (Exception e) {
-                    if (logger.isDebugEnabled()) {
-                        logger.debug("Exception closing connection", e);
-                    }
-                }
-               }
-        }
-    }
-
-    private Connection getConnection() throws NamingException, SQLException {
-       return JDBCTools.getConnection(REPOSITORY_NAME);
-    }
 
 
 }
index 1f739c1b1e953373517a0336c3b7e13e9171b567..da78c16dc42af57dfe1f39df49ddec7b3325e956 100644 (file)
  */
 package org.collectionspace.services.report.nuxeo;
 
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+
+import javax.naming.NamingException;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.Response;
+
+import net.sf.jasperreports.engine.JRException;
+import net.sf.jasperreports.engine.JasperExportManager;
+import net.sf.jasperreports.engine.JasperFillManager;
+import net.sf.jasperreports.engine.JasperPrint;
+
+import org.collectionspace.services.ReportJAXBSchema;
+import org.collectionspace.services.report.ReportResource;
 import org.collectionspace.services.report.ReportsCommon;
+import org.collectionspace.services.client.PoxPayloadIn;
+import org.collectionspace.services.client.PoxPayloadOut;
+import org.collectionspace.services.common.ResourceMap;
+import org.collectionspace.services.common.ServiceMain;
+import org.collectionspace.services.common.ServiceMessages;
+import org.collectionspace.services.common.config.ConfigReader;
+import org.collectionspace.services.common.context.ServiceContext;
+import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentException;
+import org.collectionspace.services.common.document.DocumentWrapper;
+import org.collectionspace.services.common.invocable.Invocable;
+import org.collectionspace.services.common.invocable.InvocationContext;
+import org.collectionspace.services.common.storage.JDBCTools;
+import org.collectionspace.services.jaxb.InvocableJAXBSchema;
 import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
+import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.model.PropertyException;
+import org.nuxeo.ecm.core.api.repository.RepositoryInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * ReportDocumentModelHandler
@@ -33,6 +72,200 @@ import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;
  * $LastChangedDate: $
  */
 public class ReportDocumentModelHandler extends DocHandlerBase<ReportsCommon> {
+    private final Logger logger = LoggerFactory.getLogger(ReportDocumentModelHandler.class);
+    private static String REPOSITORY_NAME = JDBCTools.NUXEO_REPOSITORY_NAME;
+    private static String REPORTS_FOLDER = "reports";
+    private static String CSID_LIST_SEPARATOR = ",";
+    
+    private static String REPORTS_STD_CSID_PARAM = "csid";
+    private static String REPORTS_STD_GROUPCSID_PARAM = "groupcsid";
+    private static String REPORTS_STD_CSIDLIST_PARAM = "csidlist";
+    private static String REPORTS_STD_TENANTID_PARAM = "tenantid";
+       
+       public Response invokeReport(
+                       ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
+                       String csid,
+                       InvocationContext invContext) throws Exception {
+               RepositoryInstance repoSession = null;
+               boolean releaseRepoSession = false;
+
+               String invocationMode = invContext.getMode();
+               String modeProperty = null;
+               HashMap<String, Object> params = new HashMap<String, Object>();
+               params.put(REPORTS_STD_TENANTID_PARAM, ctx.getTenantId());
+               boolean checkDocType = true;
+               if(Invocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = InvocableJAXBSchema.SUPPORTS_SINGLE_DOC;
+               params.put(REPORTS_STD_CSID_PARAM, invContext.getSingleCSID());
+               } else if(Invocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = InvocableJAXBSchema.SUPPORTS_DOC_LIST;
+                       List<String> csids = null;
+                       InvocationContext.ListCSIDs listThing = invContext.getListCSIDs();
+                               if(listThing!=null) {
+                                       csids = listThing.getCsid();
+                               }
+                               if(csids==null||csids.isEmpty()){
+                               throw new BadRequestException(
+                                               "ReportResource: Report invoked in list mode, with no csids in list." );
+                               }
+                               StringBuilder sb = new StringBuilder();
+                               boolean first = true;
+                               for(String csidItem : csids) {
+                                       if(first)
+                                               first = false;
+                                       else
+                                               sb.append(CSID_LIST_SEPARATOR);
+                                       sb.append(csidItem);
+                               }
+               params.put(REPORTS_STD_CSIDLIST_PARAM, sb.toString());
+               } else if(Invocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = InvocableJAXBSchema.SUPPORTS_GROUP;
+               params.put(REPORTS_STD_GROUPCSID_PARAM, invContext.getGroupCSID());
+               } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {
+                       modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;
+                       checkDocType = false;
+               } else {
+                       throw new BadRequestException("ReportResource: unknown Invocation Mode: "
+                               +invocationMode);
+               }
+               
+               RepositoryJavaClientImpl repoClient = (RepositoryJavaClientImpl)this.getRepositoryClient(ctx);
+               repoSession = this.getRepositorySession();
+               if (repoSession == null) {
+                       repoSession = repoClient.getRepositorySession();
+                       releaseRepoSession = true;
+               }
+
+               String reportFileName = null;
+               // Get properties from the batch docModel, and release the session
+               try {
+                       DocumentWrapper<DocumentModel> wrapper = repoClient.getDoc(repoSession, ctx, csid);
+                       DocumentModel docModel = wrapper.getWrappedObject();
+                       Boolean supports = (Boolean)docModel.getPropertyValue(modeProperty);
+                       if(supports == null || !supports) {
+                               throw new BadRequestException(
+                                               "ReportResource: This Report does not support Invocation Mode: "
+                                       +invocationMode);
+                       }
+               if(checkDocType) {
+                       List<String> forDocTypeList = 
+                               (List<String>)docModel.getPropertyValue(InvocableJAXBSchema.FOR_DOC_TYPES);
+                       if(forDocTypeList==null
+                                       || !forDocTypeList.contains(invContext.getDocType())) {
+                               throw new BadRequestException(
+                                               "ReportResource: Invoked with unsupported document type: "
+                                               +invContext.getDocType());
+                       }
+               }
+                       reportFileName = (String)docModel.getPropertyValue(ReportJAXBSchema.FILENAME);
+               } catch (PropertyException pe) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Property exception getting batch values: ", pe);
+                       }
+                       throw pe;
+               } catch (DocumentException de) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Problem getting batch doc: ", de);
+                       }
+                       throw de;
+               } catch (Exception e) {
+                       if (logger.isDebugEnabled()) {
+                               logger.debug("Caught exception ", e);
+                       }
+                       throw new DocumentException(e);
+               } finally {
+                       if (releaseRepoSession && repoSession != null) {
+                               repoClient.releaseRepositorySession(repoSession);
+                       }
+               }
+               return buildReportResponse(csid, params, reportFileName);
+       }
+
+
+    private Response buildReportResponse(String reportCSID, HashMap<String, Object> params, String reportFileName)
+                               throws Exception {
+               Connection conn = null;
+               Response response = null;
+       try {
+                       String fullPath = ServiceMain.getInstance().getServerRootDir() +
+                                                               File.separator + ConfigReader.CSPACE_DIR_NAME + 
+                                                               File.separator + REPORTS_FOLDER +
+                                                               // File.separator + tenantName +
+                                                               File.separator + reportFileName;
+                       conn = getConnection();
+       
+            if (logger.isTraceEnabled()) {
+               logger.trace("ReportResource for Report csid=" + reportCSID
+                               +" opening report file: "+fullPath);
+            }
+                       FileInputStream fileStream = new FileInputStream(fullPath);
+       
+               // fill the report
+                       JasperPrint jasperprint = JasperFillManager.fillReport(fileStream, params,conn);
+                       // export report to pdf and build a response with the bytes
+                       byte[] pdfasbytes = JasperExportManager.exportReportToPdf(jasperprint);
+                       
+                       // Need to set response type for what is requested...
+               response = Response.ok(pdfasbytes, "application/pdf").build();
+       
+               return response;        
+        } catch (SQLException sqle) {
+            // SQLExceptions can be chained. We have at least one exception, so
+            // set up a loop to make sure we let the user know about all of them
+            // if there happens to be more than one.
+            if (logger.isDebugEnabled()) {
+                   SQLException tempException = sqle;
+                   while (null != tempException) {
+                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());
+       
+                       // loop to the next exception
+                       tempException = tempException.getNextException();
+                   }
+            }
+            response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                               "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (JRException jre) {
+            if (logger.isDebugEnabled()) {
+               logger.debug("JR Exception: " + jre.getLocalizedMessage() + " Cause: "+jre.getCause());
+            }
+            response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                               "Invoke failed (Jasper problem) on Report csid=" + reportCSID).type("text/plain").build();
+            throw new WebApplicationException(response);
+        } catch (FileNotFoundException fnfe) {
+            if (logger.isDebugEnabled()) {
+               logger.debug("FileNotFoundException: " + fnfe.getLocalizedMessage());
+            }
+            response = Response.status(
+                    Response.Status.INTERNAL_SERVER_ERROR).entity(
+                               "Invoke failed (SQL problem) on Report csid=" + reportCSID).type("text/plain").build();
+            throw new WebApplicationException(response);
+               } finally {
+               if(conn!=null) {
+                       try {
+                       conn.close();
+                } catch (SQLException sqle) {
+                    // SQLExceptions can be chained. We have at least one exception, so
+                    // set up a loop to make sure we let the user know about all of them
+                    // if there happens to be more than one.
+                    if (logger.isDebugEnabled()) {
+                               logger.debug("SQL Exception closing connection: " 
+                                               + sqle.getLocalizedMessage());
+                    }
+                } catch (Exception e) {
+                    if (logger.isDebugEnabled()) {
+                        logger.debug("Exception closing connection", e);
+                    }
+                }
+               }
+        }
+    }
+
+    private Connection getConnection() throws NamingException, SQLException {
+       return JDBCTools.getConnection(REPOSITORY_NAME);
+    }
 
 }