]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-2496 Added handling of InitHandlers in ServiceMain, with changes to tenant...
authorLaramie Crocker <laramie@berkeley.edu>
Wed, 22 Dec 2010 20:35:20 +0000 (20:35 +0000)
committerLaramie Crocker <laramie@berkeley.edu>
Wed, 22 Dec 2010 20:35:20 +0000 (20:35 +0000)
services/client/src/main/resources/collectionspace-client.properties
services/common/src/main/config/services/tenant-bindings.xml
services/common/src/main/java/org/collectionspace/services/common/InitHandler.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/common/ServiceMain.java
services/common/src/main/java/org/collectionspace/services/common/document/IInitHandler.java [new file with mode: 0644]
services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java
services/common/src/main/resources/service.xsd

index e469b8f3764b90418131194e00bc3b148ef02a3f..4deaf2bf64208985a27695f0d12ce423306a0b64 100644 (file)
@@ -1,6 +1,9 @@
 #url of the collectionspace server\r
-cspace.url=http://localhost:8180/cspace-services/\r
+#cspace.url=http://localhost:8180/cspace-services/\r
 #cspace.url=http://localhost:8200/cspace-services/\r
+#for sockspy: \r
+cspace.url=http://localhost:8280/cspace-services/\r
+\r
 cspace.ssl=false\r
 cspace.auth=true\r
 # default user\r
index 1be456321798529e90f013787511d7aaf9094fbc..c6c662251179d3de6e39841f0352633555a547a8 100644 (file)
             <service:documentHandler xmlns:service='http://collectionspace.org/services/common/service'>
                 org.collectionspace.services.loanin.nuxeo.LoaninDocumentModelHandler
             </service:documentHandler>
+            <service:DocHandlerParams xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:classname>org.collectionspace.services.loanin.nuxeo.LoaninDocumentModelHandler</service:classname>
+                <service:params>
+                     <service:NuxeoSchemaName>loansin</service:NuxeoSchemaName>
+                     <service:DublinCoreTitle>loansin</service:DublinCoreTitle>
+                     <service:SummaryFields>loanInNumber|lenderList|loanReturnDate|uri|csid</service:SummaryFields>
+                     <service:NuxeoSchemaName>loansin</service:NuxeoSchemaName>
+                     <service:AbstractCommonListClassname>org.collectionspace.services.loanin.LoansinCommonList</service:AbstractCommonListClassname>
+                     <service:CommonListItemClassname>org.collectionspace.services.loanin.LoansinCommonList$LoaninListItem</service:CommonListItemClassname>
+                     <service:ListItemMethodName>getLoaninListItem</service:ListItemMethodName>
+                     <service:ListItemsArrays>
+                         <service:ListItemsArray>
+                             <service:setter>setLoanInNumber</service:setter>
+                             <service:element>loanInNumber</service:element>
+                             <service:container></service:container>
+                             <service:subelement></service:subelement>
+                         </service:ListItemsArray>
+
+                        <service:ListItemsArray>
+                            <service:setter>setLender</service:setter>
+                            <service:element>lenderList</service:element>
+                            <service:container>lenderGroupList</service:container>
+                            <service:subelement>lender</service:subelement>
+                        </service:ListItemsArray>
+
+                        <service:ListItemsArray>
+                            <service:setter>setLoanReturnDate</service:setter>
+                            <service:element>loanReturnDate</service:element>
+                            <service:container></service:container>
+                            <service:subelement></service:subelement>
+                        </service:ListItemsArray>
+                    </service:ListItemsArrays>
+                </service:params>
+            </service:DocHandlerParams>
             <service:validatorHandler xmlns:service='http://collectionspace.org/services/common/service'>
                 org.collectionspace.services.loanin.nuxeo.LoaninValidatorHandler
             </service:validatorHandler>
+            <service:initHandler xmlns:service='http://collectionspace.org/services/common/service'>
+                <service:classname>org.collectionspace.services.common.InitHandler</service:classname>
+                <service:fields>
+                    <service:field>ID</service:field>
+                    <service:field>Foo</service:field>
+                </service:fields>
+            </service:initHandler>
             <service:properties xmlns:service='http://collectionspace.org/services/common/service'>
                 <!-- What to use for name???
                 <types:item><types:key>objectNameProperty</types:key><types:value>objectName</types:value></types:item> -->
                 <service:part id="1" control_group="Managed"
                               versionable="true" auditable="false"
                               label="media_common" updated="" order="1">
+                    <service:properties>
+                        <types:item><types:key>authRef</types:key><types:value>contributor</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>coverage</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>creator</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>publisher</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>rightsHolder</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>subjects|subject</types:value></types:item>
+                   </service:properties>
                     <service:content contentType="application/xml">
                         <service:xmlContent
                             namespaceURI="http://collectionspace.org/services/media"
                 <service:part id="1" control_group="Managed"
                               versionable="true" auditable="false"
                               label="media_common" updated="" order="1">
+
+                    <service:properties>
+                        <types:item><types:key>authRef</types:key><types:value>contributor</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>coverage</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>creator</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>publisher</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>rightsHolder</types:value></types:item>
+                        <types:item><types:key>authRef</types:key><types:value>subjects|subject</types:value></types:item>
+                   </service:properties>
+
                     <service:content contentType="application/xml">
                         <service:xmlContent
                             namespaceURI="http://collectionspace.org/services/media"
diff --git a/services/common/src/main/java/org/collectionspace/services/common/InitHandler.java b/services/common/src/main/java/org/collectionspace/services/common/InitHandler.java
new file mode 100644 (file)
index 0000000..f8a215a
--- /dev/null
@@ -0,0 +1,102 @@
+package org.collectionspace.services.common;\r
+\r
+import com.sun.media.jai.util.DataBufferUtils;\r
+import org.collectionspace.services.common.context.ServiceContext;\r
+import org.collectionspace.services.common.document.DocumentHandler;\r
+import org.collectionspace.services.common.document.IInitHandler;\r
+import org.collectionspace.services.common.document.InvalidDocumentException;\r
+import org.collectionspace.services.common.service.ServiceBindingType;\r
+\r
+import java.sql.*;\r
+import java.util.ArrayList;\r
+import java.util.List;\r
+\r
+/**\r
+ * User: laramie\r
+ * $LastChangedRevision:  $\r
+ * $LastChangedDate:  $\r
+ */\r
+public class InitHandler implements IInitHandler {\r
+\r
+    public void onRepositoryInitialized(ServiceBindingType sbt, List<String> fields) throws Exception {\r
+          //todo: all post-init tasks for services, or delegate to services that override.\r
+          System.out.println("\r\n\r\n~~~~~~~~~~~~~ in onRepositoryInitialized with ServiceBindingType: "+sbt);\r
+\r
+        //call something like this: services.common.storage.DBUtils.addIndex(String tablename, String fields[]);\r
+        //for every field that has an authRef, do ...\r
+        //    --> Connection conn = getConnection();\r
+        //see parameter that you need for adding indices to SQL.\r
+\r
+    }\r
+     /*\r
+    private void doJDBC(){\r
+        Connection conn = null;\r
+        PreparedStatement pstmt = null;\r
+       Statement stmt = null;\r
+        // First find or create the tenants\r
+        try {\r
+            String queryTenantSQL = "UPDATE TABLE ADD KEY `tablename`.`id`...";\r
+               conn = getConnection();\r
+               // First find or create the tenants\r
+               stmt = conn.createStatement();\r
+                       ResultSet rs = stmt.executeQuery(queryTenantSQL);\r
+               ArrayList<String> existingTenants = new ArrayList<String>();\r
+                       while (rs.next()) {\r
+                               String tId = rs.getString("id");\r
+                               String tName = rs.getString("name");\r
+                               if(tenantInfo.containsKey(tId)) {\r
+                                       existingTenants.add(tId);\r
+                                       if(!tenantInfo.get(tId).equalsIgnoreCase(tName)) {\r
+                                               logger.warn("Configured name for tenant: "\r
+                                                               +tId+" in repository: "+tName\r
+                                                               +" does not match config'd name: "+ tenantInfo.get(tId));\r
+                                       }\r
+                               }\r
+                       }\r
+                       rs.close();\r
+               pstmt.close();\r
+                       stmt.close();\r
+        } catch (RuntimeException rte) {\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("Exception in createDefaultAccounts: "+\r
+                                               rte.getLocalizedMessage());\r
+                       logger.debug(rte.getStackTrace().toString());\r
+               }\r
+            throw rte;\r
+        } catch (SQLException sqle) {\r
+            // SQLExceptions can be chained. We have at least one exception, so\r
+            // set up a loop to make sure we let the user know about all of them\r
+            // if there happens to be more than one.\r
+               if (logger.isDebugEnabled()) {\r
+                       SQLException tempException = sqle;\r
+                       while (null != tempException) {\r
+                               logger.debug("SQL Exception: " + sqle.getLocalizedMessage());\r
+                               tempException = tempException.getNextException();\r
+                       }\r
+                       logger.debug(sqle.getStackTrace().toString());\r
+               }\r
+            throw new RuntimeException("SQL problem in createDefaultAccounts: ", sqle);\r
+        } catch (Exception e) {\r
+               if (logger.isDebugEnabled()) {\r
+                       logger.debug("Exception in createDefaultAccounts: "+\r
+                                               e.getLocalizedMessage());\r
+               }\r
+        } finally {\r
+               try {\r
+               if(conn!=null)\r
+                    conn.close();\r
+               if(pstmt!=null)\r
+                    pstmt.close();\r
+               if(stmt!=null)\r
+                    stmt.close();\r
+            } catch (SQLException sqle) {\r
+               if (logger.isDebugEnabled()) {\r
+                               logger.debug("SQL Exception closing statement/connection: "\r
+                                               + sqle.getLocalizedMessage());\r
+               }\r
+               }\r
+        }\r
+    }\r
+    */\r
+\r
+}\r
index 43af76e7499784545f54e4bb8798cc7e88a20801..8a28079eeafbc8e23725da453153a9ec4f5b4a2e 100644 (file)
@@ -17,15 +17,16 @@ import javax.naming.InitialContext;
 import javax.naming.NamingException;\r
 import javax.security.auth.login.LoginException;\r
 import javax.sql.DataSource;\r
-import javax.ws.rs.WebApplicationException;\r
-import javax.ws.rs.core.Response;\r
 \r
 import org.collectionspace.services.common.config.ServicesConfigReaderImpl;\r
 import org.collectionspace.services.common.config.TenantBindingConfigReaderImpl;\r
+import org.collectionspace.services.common.document.IInitHandler;\r
 import org.collectionspace.services.common.security.SecurityUtils;\r
+import org.collectionspace.services.common.service.*;\r
 import org.collectionspace.services.common.tenant.TenantBindingType;\r
 import org.collectionspace.services.common.types.PropertyItemType;\r
 import org.collectionspace.services.common.types.PropertyType;\r
+import org.collectionspace.services.nuxeo.client.java.DocHandlerBase;\r
 import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;\r
 import org.collectionspace.services.nuxeo.client.java.TenantRepository;\r
 import org.slf4j.Logger;\r
@@ -89,8 +90,7 @@ public class ServiceMain {
         return instance;\r
     }\r
 \r
-    private void initialize() throws Exception {\r
-        setServerRootDir();\r
+    private void initialize() throws Exception {        setServerRootDir();\r
         readConfig();\r
         propagateConfiguredProperties();\r
         try {\r
@@ -98,11 +98,18 @@ public class ServiceMain {
         } catch(Exception e) {\r
                logger.error("Default Account setup failed on exception: "+e.getLocalizedMessage());\r
         }\r
+        try {\r
+            //loadDocHandlers();\r
+            firePostInitHandlers();\r
+        } catch(Exception e) {\r
+            logger.error("ServiceMain.initialize firePostInitHandlers failed on exception: "+e.getLocalizedMessage());\r
+        }\r
+\r
         if (getClientType().equals(ClientType.JAVA)) {\r
             nuxeoConnector = NuxeoConnector.getInstance();\r
-            nuxeoConnector.initialize(\r
-                    getServicesConfigReader().getConfiguration().getRepositoryClient());\r
+            nuxeoConnector.initialize(getServicesConfigReader().getConfiguration().getRepositoryClient());\r
         }\r
+\r
     }\r
 \r
     /**\r
@@ -508,7 +515,86 @@ public class ServiceMain {
     private String getDefaultReaderUserID(String tenantName) {\r
        return TENANT_READER_ACCT_PREFIX+tenantName;\r
     }\r
-    \r
+\r
+    private void firePostInitHandlers() throws Exception {\r
+        Hashtable<String, TenantBindingType> tenantBindingTypeMap = tenantBindingConfigReader.getTenantBindings();\r
+        //Loop through all tenants in tenant-bindings.xml\r
+        for (TenantBindingType tbt: tenantBindingTypeMap.values()){\r
+            //String name = tbt.getName();\r
+            //String id = tbt.getId();\r
+            //Loop through all the services in this tenant\r
+            List<ServiceBindingType> sbtList = tbt.getServiceBindings();\r
+            for (ServiceBindingType sbt: sbtList){\r
+                //Get the list of InitHandler elements, extract the first one (only one supported right now) and fire it using reflection.\r
+                List<org.collectionspace.services.common.service.InitHandler> list = sbt.getInitHandler();\r
+                if (list!=null && list.size()>0){\r
+                    org.collectionspace.services.common.service.InitHandler handlerType = list.get(0);\r
+                    String initHandlerClassname = handlerType.getClassname();\r
+                    org.collectionspace.services.common.service.InitHandler.Fields ft = handlerType.getFields();\r
+                    List<String> fields = ft.getField();\r
+                    Object o = instantiate(initHandlerClassname, IInitHandler.class);\r
+                    if (o != null && o instanceof IInitHandler){\r
+                        IInitHandler handler = (IInitHandler)o;\r
+                        handler.onRepositoryInitialized(sbt, fields);\r
+                        //The InitHandler may be the default one,\r
+                        //  or specialized classes which still implement this interface and are registered in tenant-bindings.xml.\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    public Object instantiate(String clazz, Class castTo) throws Exception {\r
+        ClassLoader tccl = Thread.currentThread().getContextClassLoader();\r
+        clazz = clazz.trim();\r
+        Class<?> c = tccl.loadClass(clazz);\r
+        if (castTo.isAssignableFrom(c)) {\r
+            return c.newInstance();\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private void loadDocHandlers() throws Exception {\r
+        Hashtable<String, TenantBindingType> tenantBindingTypeMap = tenantBindingConfigReader.getTenantBindings();\r
+        for (TenantBindingType tbt: tenantBindingTypeMap.values()){\r
+            String name = tbt.getName();\r
+            String id = tbt.getId();\r
+\r
+            List<ServiceBindingType> sbtList = tbt.getServiceBindings();\r
+            for (ServiceBindingType sbt: sbtList){\r
+                DocHandlerParams params = sbt.getDocHandlerParams();\r
+                if (params!=null){\r
+                    params.getClassname();\r
+                    DocHandlerParams.Params p = params.getParams();\r
+                    DocHandlerBase.CommonListReflection clr = new DocHandlerBase.CommonListReflection();\r
+                    //List<ListItemsArray> items = p.getListItemsArrays();   //todo: this thing only returns one row. xsd is wrong.  tenant-bindings.xml has an example of multiple elements in loansin.\r
+                    List<ListItemsArray> items = /*DocHandlerParams.Params.ListItemsArrays items =*/\r
+                            p.getListItemsArrays().getListItemsArray();   //todo: this thing only returns one row. xsd is wrong.  tenant-bindings.xml has an example of multiple elements in loansin.\r
+                    int size = items.size();\r
+                    String[][] rows = new String[size][4];\r
+                    int r = 0;\r
+                    for (ListItemsArray item: items){\r
+                        String[] row = rows[r];\r
+                        row[0] = item.getSetter();\r
+                        row[1] = item.getElement();\r
+                        row[2] = item.getContainer();\r
+                        row[3] = item.getSubelement();\r
+                        r++;\r
+                    }\r
+                    clr.ListItemsArray = rows;\r
+                    clr.AbstractCommonListClassname = p.getAbstractCommonListClassname();\r
+                    clr.CommonListItemClassname = p.getCommonListItemClassname();\r
+                    clr.DublinCoreTitle = p.getDublinCoreTitle();\r
+                    clr.ListItemMethodName = p.getListItemMethodName();\r
+                    clr.NuxeoSchemaName = p.getNuxeoSchemaName();\r
+                    clr.SummaryFields = p.getSummaryFields();\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
     private Connection getConnection() throws LoginException, SQLException {\r
         InitialContext ctx = null;\r
         Connection conn = null;\r
diff --git a/services/common/src/main/java/org/collectionspace/services/common/document/IInitHandler.java b/services/common/src/main/java/org/collectionspace/services/common/document/IInitHandler.java
new file mode 100644 (file)
index 0000000..9a72c24
--- /dev/null
@@ -0,0 +1,15 @@
+package org.collectionspace.services.common.document;\r
+\r
+import org.collectionspace.services.common.context.ServiceContext;\r
+import org.collectionspace.services.common.service.ServiceBindingType;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * User: laramie\r
+ * $LastChangedRevision:  $\r
+ * $LastChangedDate:  $\r
+ */\r
+public interface IInitHandler {\r
+   public void onRepositoryInitialized(ServiceBindingType sbt, List<String> fields) throws Exception;\r
+}\r
index f29d184b4e90b44077428c35acf41da6eb5b138e..93ddb4f5eb7a7bc1a8cd2d9cfc83b79b390ca782 100644 (file)
@@ -567,8 +567,10 @@ public class RepositoryJavaClientImpl implements RepositoryClient {
             throws DocumentNotFoundException, DocumentException {
 
         DocumentFilter filter =  handler.getDocumentFilter();
-        //filter.setOrderByClause("collectionspace_core:updatedAt DESC");  //per http://issues.collectionspace.org/browse/CSPACE-705
-
+        String oldOrderBy = filter.getOrderByClause();
+        if (oldOrderBy!=null && oldOrderBy.isEmpty()){
+            filter.setOrderByClause("collectionspace_core:updatedAt DESC");  //per http://issues.collectionspace.org/browse/CSPACE-705
+        }
         QueryContext queryContext = new QueryContext(ctx, handler);
         RepositoryInstance repoSession = null;
         try {
index 7ab3b93fc014d1398498fd76d0074939f4143612..9ef2ccf2f89838672d054d7b33b911045caa0ede 100644 (file)
             <xs:element name="object" type="ServiceObjectType" minOccurs="1" maxOccurs="1"/>
             <!-- document handler to be used to process the content (need to be in classpath) -->
             <xs:element name="documentHandler" type="xs:string" minOccurs="1" maxOccurs="1"/>
+
+            <xs:element name="DocHandlerParams" type="DocHandlerParams" minOccurs="0" maxOccurs="1"/>
+
             <!-- validator handler(s) to be used to validate the content (need to be in classpath) -->
             <!-- validator handler is called for create (POST) and update (PUT) requests only -->
             <xs:element name="validatorHandler" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+            <!-- initHandler is a post-init task after the Nuxeo repository is available. -->
+            <!-- worked: <xs:element name="initHandler" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>-->
+            <xs:element name="initHandler" type="initHandler" minOccurs="0" maxOccurs="unbounded"/>
             <!-- name of the repository domain -->
             <xs:element name="repositoryDomain" type="xs:string" minOccurs="0" maxOccurs="1"/>
             <!-- repositoryWorkspaceId could be workspace id -->
         </xs:attribute>
     </xs:complexType>
 
+    <xs:complexType name="FieldsType">
+        <xs:sequence>
+            <xs:element name="field" type="xs:string"/>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="initHandler">
+        <xs:sequence>
+            <xs:element name="classname" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <!--<xs:element name="fields" type="FieldsType" minOccurs="0" maxOccurs="1"/>-->
+            <xs:element name="fields">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="field" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+                    </xs:sequence>
+                </xs:complexType>
+           </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="DocHandlerParams">
+        <xs:sequence>
+            <xs:element name="classname" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="params">
+                <xs:complexType>
+                    <xs:sequence>
+                        <xs:element name="NuxeoSchemaName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+                        <xs:element name="DublinCoreTitle" type="xs:string" minOccurs="0" maxOccurs="1"/>
+                        <xs:element name="SummaryFields" type="xs:string" minOccurs="0" maxOccurs="1"/>
+                        <xs:element name="AbstractCommonListClassname" type="xs:string" minOccurs="0" maxOccurs="1"/>
+                        <xs:element name="CommonListItemClassname" type="xs:string" minOccurs="0" maxOccurs="1"/>
+                        <xs:element name="ListItemMethodName" type="xs:string" minOccurs="0" maxOccurs="1"/>
+                        <xs:element name="ListItemsArrays" minOccurs="1" maxOccurs="1">
+                            <xs:complexType>
+                                <xs:sequence>
+                                    <xs:element name="ListItemsArray" type="ListItemsArray" minOccurs="0" maxOccurs="unbounded"/>
+                                </xs:sequence>
+                            </xs:complexType>
+                        </xs:element>
+                    </xs:sequence>
+                </xs:complexType>
+           </xs:element>
+        </xs:sequence>
+    </xs:complexType>
+
+    <xs:complexType name="ListItemsArray">
+        <xs:sequence>
+            <xs:element name="setter" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="element" type="xs:string" minOccurs="1" maxOccurs="1"/>
+            <xs:element name="container" type="xs:string" minOccurs="0" maxOccurs="1"/>
+            <xs:element name="subelement" type="xs:string" minOccurs="0" maxOccurs="1"/>
+        </xs:sequence>
+    </xs:complexType>
+
+
+
+
+
 </xs:schema>