- private final Function<SourceIdentifier, ListenableFuture<ASTSchemaSource>> requestSources = new Function<SourceIdentifier, ListenableFuture<ASTSchemaSource>>() {
- @Override
- public ListenableFuture<ASTSchemaSource> apply(final SourceIdentifier input) {
- return repository.getSchemaSource(input, ASTSchemaSource.class);
+ private final Cache<Collection<SourceIdentifier>, EffectiveModelContext> revisionCache = CacheBuilder.newBuilder()
+ .weakValues().build();
+ private final Cache<Collection<SourceIdentifier>, EffectiveModelContext> semVerCache = CacheBuilder.newBuilder()
+ .weakValues().build();
+ private final @NonNull SharedSchemaRepository repository;
+ private final @NonNull SchemaContextFactoryConfiguration config;
+
+ SharedSchemaContextFactory(final @NonNull SharedSchemaRepository repository,
+ final @NonNull SchemaContextFactoryConfiguration config) {
+ this.repository = requireNonNull(repository);
+ this.config = requireNonNull(config);
+ }
+
+ @Override
+ public @NonNull ListenableFuture<EffectiveModelContext> createEffectiveModelContext(
+ final @NonNull Collection<SourceIdentifier> requiredSources) {
+ return createSchemaContext(requiredSources,
+ config.getStatementParserMode() == StatementParserMode.SEMVER_MODE ? semVerCache : revisionCache,
+ new AssembleSources(repository.factory(), config));
+ }
+
+ private @NonNull ListenableFuture<EffectiveModelContext> createSchemaContext(
+ final Collection<SourceIdentifier> requiredSources,
+ final Cache<Collection<SourceIdentifier>, EffectiveModelContext> cache,
+ final AsyncFunction<List<IRSchemaSource>, EffectiveModelContext> assembleSources) {
+ // Make sources unique
+ final List<SourceIdentifier> uniqueSourceIdentifiers = deDuplicateSources(requiredSources);
+
+ final EffectiveModelContext existing = cache.getIfPresent(uniqueSourceIdentifiers);
+ if (existing != null) {
+ LOG.debug("Returning cached context {}", existing);
+ return immediateFluentFuture(existing);