From 19f3317b58209f97f70540cc35866e3c3d17e19c Mon Sep 17 00:00:00 2001 From: Robert Munteanu Date: Tue, 5 May 2015 12:34:31 +0300 Subject: [PATCH] OAK-2828 - Jcr builder class does not allow overriding most of its dependencies Defer configuring the Oak instance until the createRepository method is invoked. --- .../java/org/apache/jackrabbit/oak/jcr/Jcr.java | 205 ++++++++++++++++----- 1 file changed, 160 insertions(+), 45 deletions(-) diff --git a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java index 5afed7c..a20236f 100644 --- a/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java +++ b/oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/Jcr.java @@ -17,9 +17,12 @@ package org.apache.jackrabbit.oak.jcr; import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.Lists.newArrayList; import static org.apache.jackrabbit.oak.plugins.commit.JcrConflictHandler.createJcrConflictHandler; +import java.util.List; import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledExecutorService; import javax.annotation.Nonnull; @@ -58,44 +61,44 @@ import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer; import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider; import org.apache.jackrabbit.oak.spi.security.SecurityProvider; import org.apache.jackrabbit.oak.spi.state.NodeStore; - +import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard; + +/** + * Builder class which encapsulates the details of building a JCR Repository backed + * by an Oak ContentRepository instance + * + *

By default the backing ContentRepository instance will be constructed with + * reasonable defaults, but these can be overridden. Note that once one type of dependency is + * overridden all dependencies must of that type must be overridden. As an example, once {@link #with(EditorProvider)} + * is invoked, all desired EditorProviders must be provided.

+ */ public class Jcr { public static final int DEFAULT_OBSERVATION_QUEUE_LENGTH = 1000; private final Oak oak; - private final CompositeConflictHandler conflictHandler = createJcrConflictHandler(); - + + private final List repositoryInitializers = newArrayList(); + private final List queryIndexProviders = newArrayList(); + private final List commitHooks = newArrayList(); + private final List indexEditorProviders = newArrayList(); + private final List editorProviders = newArrayList(); + private final List editors = newArrayList(); + private final List observers = newArrayList(); + + private CompositeConflictHandler conflictHandler; private SecurityProvider securityProvider; + private CommitRateLimiter commitRateLimiter; + private ScheduledExecutorService scheduledExecutor; + private Executor executor; + private QueryEngineSettings queryEngineSettings; + private String defaultWorkspaceName; + private Whiteboard whiteboard; + private int observationQueueLength = DEFAULT_OBSERVATION_QUEUE_LENGTH; - private CommitRateLimiter commitRateLimiter = null; + public Jcr(Oak oak) { this.oak = oak; - - with(new InitialContent()); - - oak.with(conflictHandler); - with(new EditorHook(new VersionEditorProvider())); - - with(new SecurityProviderImpl()); - - with(new ItemSaveValidatorProvider()); - with(new NameValidatorProvider()); - with(new NamespaceEditorProvider()); - with(new TypeEditorProvider()); - with(new ConflictValidatorProvider()); - with(new AtomicCounterEditorProvider()); - with(new ReferenceEditorProvider()); - with(new ReferenceIndexProvider()); - - with(new PropertyIndexEditorProvider()); - with(new NodeCounterEditorProvider()); - - with(new PropertyIndexProvider()); - with(new OrderedPropertyIndexProvider()); - with(new NodeTypeIndexProvider()); - - with(new OrderedPropertyIndexEditorProvider()); } public Jcr() { @@ -108,44 +111,43 @@ public class Jcr { @Nonnull public final Jcr with(@Nonnull RepositoryInitializer initializer) { - oak.with(checkNotNull(initializer)); - return this; + repositoryInitializers.add(checkNotNull(initializer)); + return this; } @Nonnull public final Jcr with(@Nonnull QueryIndexProvider provider) { - oak.with(checkNotNull(provider)); + queryIndexProviders.add(checkNotNull(provider)); return this; } @Nonnull public final Jcr with(@Nonnull IndexEditorProvider indexEditorProvider) { - oak.with(checkNotNull(indexEditorProvider)); + indexEditorProviders.add(checkNotNull(indexEditorProvider)); return this; } @Nonnull public final Jcr with(@Nonnull CommitHook hook) { - oak.with(checkNotNull(hook)); + commitHooks.add(checkNotNull(hook)); return this; } @Nonnull public final Jcr with(@Nonnull EditorProvider provider) { - oak.with(checkNotNull(provider)); + editorProviders.add(checkNotNull(provider)); return this; } @Nonnull public final Jcr with(@Nonnull Editor editor) { - oak.with(checkNotNull(editor)); + editors.add(checkNotNull(editor)); return this; } @Nonnull public final Jcr with(@Nonnull SecurityProvider securityProvider) { - oak.with(checkNotNull(securityProvider)); - this.securityProvider = securityProvider; + this.securityProvider = checkNotNull(securityProvider); return this; } @@ -157,19 +159,19 @@ public class Jcr { @Nonnull public final Jcr with(@Nonnull ScheduledExecutorService executor) { - oak.with(checkNotNull(executor)); + this.scheduledExecutor = checkNotNull(executor); return this; } @Nonnull public final Jcr with(@Nonnull Executor executor) { - oak.with(checkNotNull(executor)); + this.executor = checkNotNull(executor); return this; } @Nonnull public final Jcr with(@Nonnull Observer observer) { - oak.with(checkNotNull(observer)); + observers.add(checkNotNull(observer)); return this; } @@ -187,18 +189,131 @@ public class Jcr { @Nonnull public Jcr with(CommitRateLimiter commitRateLimiter) { - oak.with(commitRateLimiter); - this.commitRateLimiter = commitRateLimiter; + this.commitRateLimiter = checkNotNull(commitRateLimiter); return this; } @Nonnull - public Jcr with(QueryEngineSettings qs) { - oak.with(qs); + public Jcr with(@Nonnull QueryEngineSettings qs) { + this.queryEngineSettings = checkNotNull(qs); return this; } + + @Nonnull + public Jcr with(@Nonnull String defaultWorkspaceName) { + this.defaultWorkspaceName = checkNotNull(defaultWorkspaceName); + return this; + } + + @Nonnull + public Jcr with(@Nonnull Whiteboard whiteboard) { + this.whiteboard = checkNotNull(whiteboard); + return this; + } public Repository createRepository() { + + // whiteboard + if ( whiteboard != null ) { + oak.with(whiteboard); + } + + // repository initializers + if ( repositoryInitializers.isEmpty() ) { + repositoryInitializers.add(new InitialContent()); + } + for ( RepositoryInitializer repositoryInitializer : repositoryInitializers ) { + oak.with(repositoryInitializer); + } + + // query index providers + if ( queryIndexProviders.isEmpty() ) { + with(new ReferenceIndexProvider()); + with(new PropertyIndexProvider()); + with(new OrderedPropertyIndexProvider()); + with(new NodeTypeIndexProvider()); + } + for ( QueryIndexProvider queryIndexProvider : queryIndexProviders ) { + oak.with(queryIndexProvider); + } + + // commit hooks + if ( commitHooks.isEmpty() ) { + commitHooks.add(new EditorHook(new VersionEditorProvider())); + } + for ( CommitHook commitHook : commitHooks) { + oak.with(commitHook); + } + + // conflict handlers + if ( conflictHandler == null ) { + conflictHandler = createJcrConflictHandler(); + } + oak.with(conflictHandler); + + // index editor providers + if ( indexEditorProviders.isEmpty() ) { + indexEditorProviders.add(new ReferenceEditorProvider()); + indexEditorProviders.add(new PropertyIndexEditorProvider()); + indexEditorProviders.add(new NodeCounterEditorProvider()); + indexEditorProviders.add(new OrderedPropertyIndexEditorProvider()); + } + for ( IndexEditorProvider indexEditorProvider : indexEditorProviders ) { + oak.with(indexEditorProvider); + } + + // editors + for ( Editor editor : editors ) { + oak.with(editor); + } + + // editor providers + if ( editorProviders.isEmpty() ) { + editorProviders.add(new ItemSaveValidatorProvider()); + editorProviders.add(new NameValidatorProvider()); + editorProviders.add(new NamespaceEditorProvider()); + editorProviders.add(new TypeEditorProvider()); + editorProviders.add(new ConflictValidatorProvider()); + editorProviders.add(new AtomicCounterEditorProvider()); + } + for ( EditorProvider editorProvider : editorProviders) { + oak.with(editorProvider); + } + + // securityProvider + if ( securityProvider == null ) { + securityProvider = new SecurityProviderImpl(); + } + oak.with(securityProvider); + + // executors + if ( scheduledExecutor != null ) { + oak.with(scheduledExecutor); + } + if ( executor != null ) { + oak.with(executor); + } + + // observers + for ( Observer observer: observers ) { + oak.with(observer); + } + + // commit rate limiter + if ( commitRateLimiter != null ) { + oak.with(commitRateLimiter); + } + + // query engine settings + if ( queryEngineSettings != null ) { + oak.with(queryEngineSettings); + } + + // default workspace name + if ( defaultWorkspaceName != null ) { + oak.with(defaultWorkspaceName); + } + return new RepositoryImpl( oak.createContentRepository(), oak.getWhiteboard(), -- 2.3.6