Class LazyCreationServiceImpl

  • All Implemented Interfaces:
    LazyCreationService

    public class LazyCreationServiceImpl
    extends Object
    implements LazyCreationService
    Implementation of the LazyCreationService. Uses SequencerService to at least locally avoid conflicts by locking the parent of the created resource. If two nodes of a cluster try to create the same resource, anyway, one of the transactions is rolled back. It will just be logged and ignored.
    • Constructor Detail

      • LazyCreationServiceImpl

        public LazyCreationServiceImpl()
    • Method Detail

      • getOrCreate

        public <T> T getOrCreate​(org.apache.sling.api.resource.ResourceResolver resolver,
                                 String path,
                                 LazyCreationService.RetrievalStrategy<T> getter,
                                 LazyCreationService.CreationStrategy creator,
                                 Map<String,​Object> parentProperties)
                          throws javax.jcr.RepositoryException
        Description copied from interface: LazyCreationService
        Retrieves a resource or applies a creation strategy to be carried out with an admin resolver to create it.

        It is an error if getter still returns null after creator is executed.

        Specified by:
        getOrCreate in interface LazyCreationService
        Type Parameters:
        T - the type the LazyCreationService.RetrievalStrategy returns.
        Parameters:
        resolver - the users resolver. If the resource needed to be created, that is getter returns null, we create it and call a Session.refresh(boolean)(true) on this session before we call getter again. Passed as a parameter to getter.
        path - the absolute path at which the creator creates the resource. Passed as a parameter to getter and creator.
        getter - side effect free function to retrieve the resource. This can be executed several times in this process.
        creator - a strategy to create the resource. Only called when the resource doesn't exist. Is only called after the parent of path is created.
        parentProperties - properties with which non-existing parents of path are created (ResourceResolver.create(Resource, String, Map)).
        Returns:
        the object.
        Throws:
        javax.jcr.RepositoryException
      • getOrCreate

        public <T> T getOrCreate​(org.apache.sling.api.resource.ResourceResolver resolver,
                                 String path,
                                 LazyCreationService.RetrievalStrategy<T> getter,
                                 LazyCreationService.CreationStrategy creator,
                                 LazyCreationService.InitializationStrategy initializer,
                                 Map<String,​Object> parentProperties)
                          throws javax.jcr.RepositoryException,
                                 org.apache.sling.api.resource.PersistenceException
        Description copied from interface: LazyCreationService
        Retrieves a resource or applies a creation and initialization strategy to be carried out with an admin resolver to create it, for resource intensive initialization processes that should not performed twice in the cluster. The resource is locked for the cluster with LockManager during that time.

        It is an error if getter still returns null after creator is executed.

        Specified by:
        getOrCreate in interface LazyCreationService
        Type Parameters:
        T - the type the LazyCreationService.RetrievalStrategy returns.
        Parameters:
        resolver - the users resolver. If the resource needed to be created, that is getter returns null, we create it and call a Session.refresh(boolean)(true) on this session before we call getter again. Passed as a parameter to getter.
        path - the absolute path at which the creator creates the resource. Passed as a parameter to getter and creator.
        getter - side effect free function to retrieve the resource. This can be executed several times in this process.
        creator - a strategy to create the resource. Only called when the resource doesn't exist. Is only called after the parent of path is created. This should not perform any resource intensive actions - these should be done in initializer.
        initializer - the resource intensive part of the resource creation
        parentProperties - properties with which non-existing parents of path are created (ResourceResolver.create(Resource, String, Map)).
        Returns:
        the object.
        Throws:
        javax.jcr.RepositoryException
        org.apache.sling.api.resource.PersistenceException
      • getOrCreate

        public <T> T getOrCreate​(org.apache.sling.api.resource.ResourceResolver resolver,
                                 String path,
                                 LazyCreationService.RetrievalStrategy<T> getter,
                                 LazyCreationService.CreationStrategy creator,
                                 LazyCreationService.ParentCreationStrategy parentCreationStrategy)
                          throws javax.jcr.RepositoryException
        Description copied from interface: LazyCreationService
        Retrieves a resource or applies a creation strategy to be carried out with an admin resolver to create it.

        It is an error if getter still returns null after creator is executed.

        Specified by:
        getOrCreate in interface LazyCreationService
        Type Parameters:
        T - the type the LazyCreationService.RetrievalStrategy returns.
        Parameters:
        resolver - the users resolver. If the resource needed to be created, that is getter returns null, we create it and call a Session.refresh(boolean)(true) on this session before we call getter again. Passed as a parameter to getter.
        path - the absolute path at which the creator creates the resource. Passed as a parameter to getter and creator.
        getter - side effect free function to retrieve the resource. This can be executed several times in this process.
        creator - a strategy to create the resource. Only called when the resource doesn't exist. Is only called after the parent of path is created.
        parentCreationStrategy - strategy with which non-existing parents of path are created.
        Returns:
        the object.
        Throws:
        javax.jcr.RepositoryException
      • getOrCreate

        public <T> T getOrCreate​(org.apache.sling.api.resource.ResourceResolver resolver,
                                 String path,
                                 LazyCreationService.RetrievalStrategy<T> getter,
                                 LazyCreationService.CreationStrategy creator,
                                 LazyCreationService.InitializationStrategy initializer,
                                 LazyCreationService.ParentCreationStrategy parentCreationStrategy)
                          throws javax.jcr.RepositoryException,
                                 org.apache.sling.api.resource.PersistenceException
        Retrieves a resource or applies a creation and initialization strategy to be carried out with an admin resolver to create it, for resource intensive initialization processes that should not performed twice in the cluster. The resource is locked for the cluster with LockManager during that time.

        It is an error if getter still returns null after creator is executed.

        We create the item in two steps. First, it is created and JCR-locked. Then it is initialized and JCR-unlocked. So, when trying to retrieve the item, we check that it is not locked, too, to verify that it is not in construction. The resource is assumed fully initialized if it exists and is not locked. We put the current time into lastupdatetime to keep track how long it is locked and whether the lock must be broken. Since we can only lock the item after the creation is committed, we set jcr:lastModified only after locking and check this must be set when retrieving the item.

        If the item exists but is locked, we wait until it is unlocked and then return what's there. If we exceed the LazyCreationServiceImpl.Configuration.lazycreation_maximumlockwait() when waiting for the lock, we break the lock and create it ourselves.

        Specified by:
        getOrCreate in interface LazyCreationService
        Type Parameters:
        T - the type the LazyCreationService.RetrievalStrategy returns.
        Parameters:
        resolver - the users resolver. If the resource needed to be created, that is getter returns null, we create it and call a Session.refresh(boolean)(true) on this session before we call getter again. Passed as a parameter to getter.
        path - the absolute path at which the creator creates the resource. Passed as a parameter to getter and creator.
        getter - side effect free function to retrieve the resource. This can be executed several times in this process.
        creator - a strategy to create the resource. Only called when the resource doesn't exist. Is only called after the parent of path is created.
        initializer - the resource intensive part of the resource creation
        parentCreationStrategy - strategy with which non-existing parents of path are created.
        Returns:
        the object.
        Throws:
        javax.jcr.RepositoryException
        org.apache.sling.api.resource.PersistenceException
      • createUninitializedResource

        protected org.apache.sling.api.resource.Resource createUninitializedResource​(org.apache.sling.api.resource.ResourceResolver adminResolver,
                                                                                     org.apache.sling.api.resource.Resource parentResource,
                                                                                     String path,
                                                                                     LazyCreationService.CreationStrategy creator)
      • tryToLockResource

        protected javax.jcr.lock.Lock tryToLockResource​(String path,
                                                        org.apache.sling.api.resource.ResourceResolver adminResolver)
                                                 throws javax.jcr.RepositoryException,
                                                        org.apache.sling.api.resource.PersistenceException
        If it is not initialized, try to lock it for up to LazyCreationServiceImpl.Configuration.lazycreation_maximumlockwait().
        Returns:
        the lock it is locked, null if it is already initialized by someone else
        Throws:
        javax.jcr.lock.LockException - if we couldn't get a lock
        javax.jcr.RepositoryException
        org.apache.sling.api.resource.PersistenceException
      • resourceIsInitialized

        protected boolean resourceIsInitialized​(org.apache.sling.api.resource.ResourceResolver resolver,
                                                String path)
                                         throws javax.jcr.RepositoryException
        Throws:
        javax.jcr.RepositoryException
      • safeCreateParent

        protected org.apache.sling.api.resource.Resource safeCreateParent​(org.apache.sling.api.resource.ResourceResolver adminResolver,
                                                                          String path,
                                                                          int level,
                                                                          LazyCreationService.ParentCreationStrategy parentCreationStrategy)
                                                                   throws javax.jcr.RepositoryException
        Tries to create the parent while catching exceptions that could be triggered by someone having created it in parallel in the meantime. Includes commit and locks path on this node.
        Throws:
        javax.jcr.RepositoryException
      • refreshSession

        protected void refreshSession​(org.apache.sling.api.resource.ResourceResolver resolver,
                                      boolean keepChanges)
        Resets unmodified resources to the currently saved state.
      • createAdministrativeResolver

        protected org.apache.sling.api.resource.ResourceResolver createAdministrativeResolver()
        Make administrative resolver with the necessary permissions to create stuff. Remember to close it!
      • deactivate

        protected void deactivate()