]> git.aero2k.de Git - tmp/jakarta-migration.git/commitdiff
CSPACE-5271: Reworked UriTemplateRegistry to make the registry's entries tenant-quali...
authorAron Roberts <aron@socrates.berkeley.edu>
Fri, 10 Aug 2012 03:42:12 +0000 (20:42 -0700)
committerAron Roberts <aron@socrates.berkeley.edu>
Fri, 10 Aug 2012 03:42:12 +0000 (20:42 -0700)
services/JaxRsServiceProvider/src/main/java/org/collectionspace/services/jaxrs/CollectionSpaceJaxRsApplication.java
services/authority/service/src/main/java/org/collectionspace/services/common/vocabulary/AuthorityResource.java
services/common/src/main/java/org/collectionspace/services/common/ResourceBase.java
services/common/src/main/java/org/collectionspace/services/common/StoredValuesUriTemplate.java
services/common/src/main/java/org/collectionspace/services/common/UriTemplateRegistry.java
services/common/src/main/java/org/collectionspace/services/common/UriTemplateRegistryHolder.java [new file with mode: 0644]
services/contact/service/src/main/java/org/collectionspace/services/contact/AuthorityResourceWithContacts.java

index c34b83663b0a557f9e64d146a70daa36ebbe6245..6910ea3f4ce4b634d0c3cf59aa44ff62e970e04e 100644 (file)
@@ -82,12 +82,12 @@ import org.jboss.resteasy.spi.ResteasyProviderFactory;
  * $LastChangedDate$
  */
 public class CollectionSpaceJaxRsApplication extends Application
-                                       implements ResourceMapHolder {
+                                       implements ResourceMapHolder, UriTemplateRegistryHolder {
 
     private Set<Object> singletons = new HashSet<Object>();
     private Set<Class<?>> empty = new HashSet<Class<?>>();    
     private ResourceMap resourceMap = new ResourceMapImpl();
-    private UriTemplateRegistry uriTemplateRegistry = new UriTemplateRegistry();
+    private static UriTemplateRegistry uriTemplateRegistry = new UriTemplateRegistry();
     private ServletContext servletContext = null;
 
     public CollectionSpaceJaxRsApplication() {         
@@ -129,6 +129,7 @@ public class CollectionSpaceJaxRsApplication extends Application
 
         singletons.add(new IDResource());
         
+        buildUriTemplateRegistry();
         // FIXME: Temporary for CSPACE-5271 - please remove once
         // that issue is resolved
         uriTemplateRegistry.dump();
@@ -144,16 +145,35 @@ public class CollectionSpaceJaxRsApplication extends Application
     private void addResourceToMapAndSingletons(ResourceBase resource) {
         singletons.add(resource);
         resourceMap.put(resource.getServiceName(), resource);
+    }
+    
+    /**
+     *  Build a registry of URI templates by querying each resource
+     *  for its own entry in the registry.
+     * 
+     *  That entry consists of a tenant-qualified map of URI templates, each
+     *  associated with a specific document type
+     */
+    private void buildUriTemplateRegistry() {
+        ResourceBase resource = null;
+        ResourceMap resources = getResourceMap();
+        for (Map.Entry<String, ResourceBase> entry : resources.entrySet()) {
+            resource = entry.getValue();
+            System.out.println(resource.getServiceName()); // for debugging
+            getUriTemplateRegistry().putAll(resource.getUriRegistryEntries());
+            getUriTemplateRegistry().dump(); // for debugging
+        }
         // Contacts itself should not have an entry in the URI template registry;
         // there should be a Contacts entry in that registry only for use in
         // building URIs for resources that have contacts as a sub-resource
         //
         // FIXME: There may be a more elegant way to filter this out; or it may
         // fall out during implementation of CSPACE-2698
-        if (! (resource instanceof ContactResource)) {
-            uriTemplateRegistry.putAll(resource.getUriTemplateMap());
-        }
+        //
+        // final String CONTACT_DOCTYPE = "Contact";
+        // uriTemplateRegistry.remove(CONTACT_DOCTYPE);
     }
+    
 
     @Override
     public Set<Class<?>> getClasses() {
@@ -169,6 +189,10 @@ public class CollectionSpaceJaxRsApplication extends Application
         return resourceMap;
     }
     
+    public UriTemplateRegistry getUriTemplateRegistry() {
+        return uriTemplateRegistry;
+    }
+    
     public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
     }
index 852546b014c046c7f2c35db683be0b8790a7d6b6..37aa1ae66b4404402d0c4f770fb784a977609948 100644 (file)
@@ -961,20 +961,27 @@ public abstract class AuthorityResource<AuthCommon, AuthItemHandler>
         }
     }
     
-    public String getItemDocType() {
-        return super.getDocType(getItemServiceName());
+    protected String getItemDocType(String tenantId) {
+        return super.getDocType(tenantId, getItemServiceName());
     }
 
+   /**
+    * Constructs and returns a map of URI templates for the current resource,
+    * for the specified tenant
+    * 
+    * @param tenantId a tenant ID
+    * @return a map of URI templates for the current resource, for the specified tenant
+    */
     @Override
-    public Map<String,StoredValuesUriTemplate> getUriTemplateMap() {
-        // Get resource URI template from superclass
-        Map<String,StoredValuesUriTemplate> uriTemplateMap = super.getUriTemplateMap();
-        // Add item URI template, and return both templates in the map
-        String itemDocType = getItemDocType();
-        StoredValuesUriTemplate itemUriTemplate = getUriTemplate(UriTemplateFactory.ITEM);
+    protected Map<String,StoredValuesUriTemplate> getUriTemplateMap(String tenantId) {
+        // Get the resource URI template from the superclass
+        Map<String,StoredValuesUriTemplate> uriTemplateMap = super.getUriTemplateMap(tenantId);
+        // Add the item URI template here, and return both templates in the map
+        String itemDocType = getItemDocType(tenantId);
         if (itemDocType == null) {
             return uriTemplateMap; // return map as obtained from superclass
         }
+        StoredValuesUriTemplate itemUriTemplate = getUriTemplate(UriTemplateFactory.ITEM);
         if (itemUriTemplate == null) {
             return uriTemplateMap; // return map as obtained from superclass
         }
index 6d2fec6b0df40a068bac89f975e1cbccf5200f9e..0a3ba97f4768b5fcb4e0617f90dba125152f5d94 100644 (file)
@@ -413,41 +413,54 @@ public abstract class ResourceBase
        return getDocModelForAuthorityItem(repoSession, RefName.AuthorityItem.parse(refName));\r
     }\r
     \r
-    public String getDocType() {\r
-        return getDocType(getServiceName());\r
+    protected String getDocType(String tenantId) {\r
+        return getDocType(tenantId, getServiceName());\r
     }\r
-        \r
-    // FIXME: The technique in getDocType(String) may well be a dreadful hack, just to get this initially working.\r
-    //\r
-    // Question:\r
-    // At the point we're seeking to populate docTypes in the uriTemplateRegistry, during system startup,\r
-    // we're not yet logged into any tenant, but instead it appears we are acting as the user SPRING_ADMIN.\r
-    // Could this potentially suggest reasonable method(s), other than those below, which reads from\r
-    // tenant bindings configuration for an arbitrary tenant, by which we can obtain the docType(s)\r
-    // associated with the current resource?\r
     \r
-    public String getDocType(String serviceName) {\r
+    // FIXME: This method may properly belong in a different services package or class.\r
+    protected String getDocType(String tenantId, String serviceName) {\r
         String docType = "";\r
-        String anyTenantId = "";\r
-        TenantBindingConfigReaderImpl reader = ServiceMain.getInstance().getTenantBindingConfigReader();\r
-        // FIXME: Makes the likely unsupportable assumption that the list of service names and associated\r
-        // document types is materially identical across tenants\r
-        anyTenantId = getAnyTenantId(reader);\r
-        if (Tools.notBlank(anyTenantId)) {\r
-            ServiceBindingType sb = reader.getServiceBinding(anyTenantId, serviceName);\r
-            docType = sb.getObject().getName(); // reads the Nuxeo Document Type from tenant bindings configuration\r
+        if (Tools.notBlank(tenantId)) {\r
+            ServiceBindingType sb = getTenantBindingsReader().getServiceBinding(tenantId, serviceName);\r
+            docType = sb.getObject().getName(); // Reads the Nuxeo Document Type from tenant bindings configuration\r
         }\r
         return docType;\r
     }\r
     \r
-    public Map<String,StoredValuesUriTemplate> getUriTemplateMap() {\r
-        Map<String,StoredValuesUriTemplate> uriTemplateMap = new HashMap<String,StoredValuesUriTemplate>();\r
-        // Construct and return a resource URI template as the sole item in the map\r
-        String docType = getDocType();\r
-        StoredValuesUriTemplate resourceUriTemplate = getUriTemplate(UriTemplateFactory.RESOURCE);\r
+    /**\r
+     * Returns a UriRegistry entry: a map of tenant-qualified URI templates\r
+     * for the current resource, for all tenants\r
+     * \r
+     * @return a map of URI templates for the current resource, for all tenants\r
+     */\r
+    public HashMap<String,Map<String,StoredValuesUriTemplate>> getUriRegistryEntries() {\r
+        HashMap<String,Map<String,StoredValuesUriTemplate>> uriRegistryEntriesMap =\r
+                new HashMap<String, Map<String,StoredValuesUriTemplate>>();\r
+        List<String> tenantIds = getTenantIds();\r
+        for (String tenantId : tenantIds) {\r
+            uriRegistryEntriesMap.put(tenantId, getUriTemplateMap(tenantId));\r
+        }\r
+        return uriRegistryEntriesMap;\r
+    }\r
+    \r
+   \r
+   /**\r
+    * Constructs and returns a map of URI templates for the current resource,\r
+    * for the specified tenant\r
+    * \r
+    * @param tenantId a tenant ID\r
+    * @return a map of URI templates for the current resource, for the specified tenant\r
+    */\r
+   protected Map<String,StoredValuesUriTemplate> getUriTemplateMap(String tenantId) {\r
+        Map<String,StoredValuesUriTemplate> uriTemplateMap = new HashMap<String, StoredValuesUriTemplate>();\r
+        if (tenantId == null) {\r
+            return uriTemplateMap; // return an empty map\r
+        }\r
+        String docType = getDocType(tenantId);\r
         if (docType == null) {\r
             return uriTemplateMap; // return an empty map\r
         }\r
+        StoredValuesUriTemplate resourceUriTemplate = getUriTemplate(UriTemplateFactory.RESOURCE);\r
         if (resourceUriTemplate == null) {\r
             return uriTemplateMap; // return an empty map\r
         }\r
@@ -455,6 +468,13 @@ public abstract class ResourceBase
         return uriTemplateMap;\r
     }\r
     \r
+    /**\r
+     * Returns a UriTemplate of the appropriate type, populated with the\r
+     * current service name as one of its stored values.\r
+     * \r
+     * @param type a UriTemplate type\r
+     * @return a UriTemplate of the appropriate type\r
+     */\r
     protected StoredValuesUriTemplate getUriTemplate(UriTemplateFactory.UriTemplateType type) {\r
         Map<String,String> storedValuesMap = new HashMap<String,String>();\r
         storedValuesMap.put(UriTemplateFactory.SERVICENAME_VAR, getServiceName());\r
@@ -463,19 +483,37 @@ public abstract class ResourceBase
         return template;\r
     }\r
 \r
-    public String getAnyTenantId(TenantBindingConfigReaderImpl reader) {\r
-        String anyTenantId = "";\r
-        Hashtable<String, TenantBindingType> tenantBindings = reader.getTenantBindings();\r
+    /**\r
+     * Returns a list of tenant IDs, from tenant bindings configuration\r
+     * \r
+     * @return a list of tenant IDs\r
+     */\r
+    // FIXME: This method may properly belong in a different services package or class.\r
+    protected List<String> getTenantIds() {\r
+        List<String> tenantIds = new ArrayList<String>();\r
+        String tenantId;\r
+        Hashtable<String, TenantBindingType> tenantBindings =\r
+                getTenantBindingsReader().getTenantBindings();\r
         if (tenantBindings != null && !tenantBindings.isEmpty()) {\r
             Enumeration keys = tenantBindings.keys();\r
             while (keys.hasMoreElements()) {\r
-               anyTenantId = (String) keys.nextElement();\r
-               if (Tools.notBlank(anyTenantId)) {\r
-                   break;\r
+               tenantId = (String) keys.nextElement();\r
+               if (Tools.notBlank(tenantId)) {\r
+                   tenantIds.add(tenantId);\r
                }\r
             }\r
         }\r
-        return anyTenantId;\r
+        return tenantIds;\r
     }\r
+    \r
+    /**\r
+     * Returns a reader for reading values from tenant bindings configuration\r
+     * \r
+     * @return a tenant bindings configuration reader\r
+     */\r
+    protected TenantBindingConfigReaderImpl getTenantBindingsReader() {\r
+        return ServiceMain.getInstance().getTenantBindingConfigReader();\r
+    }\r
+\r
 \r
 }\r
index 60fb2340fb91379c770378f72cdc0ab8dd13244a..315f2898ce3b9110fc836893b713b592012d6526 100644 (file)
@@ -35,10 +35,11 @@ import org.slf4j.LoggerFactory;
  * replace variables within the template.
  *
  * In this subclass of UriTemplate, some of the values which will replace
- * variables in an internal URI template are static, and can be stored alongside
- * the URI template for reuse. Additional values that will replace variables
- * within the template are also dynamically accepted, and will be merged with
- * stored values when building URIs.
+ * variables in an internal URI template are typically stable / static, and
+ * can be stored alongside the URI template for reuse each time that a URI
+ * is built from the template. Additional values that will replace variables
+ * within the template on a one-off basis are also dynamically accepted,
+ * and will be merged with the previously-stored values when building URIs.
  */
 public class StoredValuesUriTemplate extends UriTemplate {
 
@@ -72,10 +73,11 @@ public class StoredValuesUriTemplate extends UriTemplate {
     }
 
     /**
-     * Builds a URI string from a combination of previously-stored values, if
-     * any (such as static URI path components) and additional values, if any
-     * (such as resource identifiers), both of which will replace variables
-     * within the URI template.
+     * Builds a URI string from a combination of values previously stored
+     * along with the template, if any (typically stable URI path components,
+     * such as "intakes" and "personauthorities") and additional values, if any
+     * (typically CSIDs and URN-based resource identifiers), both of which will
+     * replace variables within the URI template.
      *
      * @param additionalValuesMap an optional map of values that will replace
      * variables within the URI template
index 18131a825f21c200ce1c8e0a5645af16fa4181de..3929120e0511809188a60bd2bccc7ce50e3c5298 100644 (file)
 package org.collectionspace.services.common;\r
 \r
 import java.util.HashMap;\r
+import java.util.Map;\r
 \r
 /**\r
  * UriTemplateRegistry.java\r
  *\r
- * Maps document types to templates for building URIs, used in turn for\r
- * accessing instances of those documents.\r
+ * Maps document types to templates for building URIs, per tenant.\r
  */\r
-public class UriTemplateRegistry extends HashMap<String, StoredValuesUriTemplate> {\r
+public class UriTemplateRegistry extends HashMap<String, Map<String, StoredValuesUriTemplate>> {\r
 \r
+    // For debugging\r
     public void dump() {\r
-        for (String docTypeKey : this.keySet()) {\r
-            StoredValuesUriTemplate uriTemplate = this.get(docTypeKey);\r
-            System.out.println("Key = " + docTypeKey + ", Value = " + uriTemplate.getUriTemplateType() + " : " + uriTemplate.toString());\r
+        for (String tenantId : this.keySet()) {\r
+            System.out.println("###############################");\r
+            System.out.println("Tenant ID = " + tenantId);\r
+            System.out.println("###############################");\r
+            for (Map.Entry<String, StoredValuesUriTemplate> uriTemplateEntry : this.get(tenantId).entrySet()) {\r
+                System.out.println("Key = " + uriTemplateEntry.getKey()\r
+                        + ", Value = " + uriTemplateEntry.getValue().getUriTemplateType()\r
+                        + " : " + uriTemplateEntry.getValue().toString());\r
+            }\r
         }\r
     }\r
 }\r
diff --git a/services/common/src/main/java/org/collectionspace/services/common/UriTemplateRegistryHolder.java b/services/common/src/main/java/org/collectionspace/services/common/UriTemplateRegistryHolder.java
new file mode 100644 (file)
index 0000000..a3ab98b
--- /dev/null
@@ -0,0 +1,6 @@
+
+package org.collectionspace.services.common;
+
+public interface UriTemplateRegistryHolder {
+       public UriTemplateRegistry getUriTemplateRegistry();
+}
index 9d6f219ea70c89f16521869d08a100f22a7d13e5..fc581dd2781852196a22a11e78e9e3f2614def78 100644 (file)
@@ -297,24 +297,31 @@ public abstract class AuthorityResourceWithContacts<AuthCommon, AuthItemHandler>
         }
     }
     
-    public String getContactDocType() {
+    protected String getContactDocType() {
         return ContactConstants.NUXEO_DOCTYPE;
     }
 
-    // This currently populates only one entry in the UriTemplateRegistry
+   /**
+    * Constructs and returns a map of URI templates for the current resource,
+    * for the specified tenant
+    * 
+    * @param tenantId a tenant ID
+    * @return a map of URI templates for the current resource, for the specified tenant
+    */
+    // FIXME: This method currently populates only one entry in the UriTemplateRegistry
     // for the Contacts docType, even though contacts can be a sub-resource of
     // multiple authority item resources.  (This method may be called more than once,
     // but each time the existing item with the same key in the map is overwritten.)
     @Override
-    public Map<String,StoredValuesUriTemplate> getUriTemplateMap() {
-        // Get resource and item URI templates from superclass
-        Map<String,StoredValuesUriTemplate> uriTemplateMap = super.getUriTemplateMap();
-        // Add contact URI template, and return all three templates in the map
+    protected Map<String,StoredValuesUriTemplate> getUriTemplateMap(String tenantId) {
+        // Get the resource and item URI templates from the superclass
+        Map<String,StoredValuesUriTemplate> uriTemplateMap = super.getUriTemplateMap(tenantId);
+        // Add the contact URI template here, and return all three templates in the map
         String contactDocType = getContactDocType();
-        StoredValuesUriTemplate contactUriTemplate = getUriTemplate(UriTemplateFactory.CONTACT);
         if (contactDocType == null) {
             return uriTemplateMap; // return map as obtained from superclass
         }
+        StoredValuesUriTemplate contactUriTemplate = getUriTemplate(UriTemplateFactory.CONTACT);
         if (contactUriTemplate == null) {
             return uriTemplateMap; // return map as obtained from superclass
         }