All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mapsmessaging.storage.StorageFactoryFactory Maven / Gradle / Ivy

There is a newer version: 2.4.10
Show newest version
/*
 *   Copyright [2020 - 2022]   [Matthew Buckton]
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 *
 */

package io.mapsmessaging.storage;

import io.mapsmessaging.logging.Logger;
import io.mapsmessaging.logging.LoggerFactory;
import io.mapsmessaging.storage.impl.cache.Cache;
import io.mapsmessaging.storage.impl.cache.CacheLayer;
import io.mapsmessaging.storage.logging.StorageLogMessages;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;
import lombok.SneakyThrows;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@SuppressWarnings("java:S3740") // This is not how ServiceLoaders work, we can not get a generic load
class StorageFactoryFactory {

  private static final Logger logger = LoggerFactory.getLogger(StorageFactoryFactory.class);

  private static final StorageFactoryFactory instance = new StorageFactoryFactory();

  private final List storageFactories;
  private final List caches;
  private final List layered = new ArrayList<>();
  private final List known = new ArrayList<>();

  private StorageFactoryFactory() {
    ServiceLoader serviceLoader = ServiceLoader.load(StorageFactory.class);
    ServiceLoader serviceCaches = ServiceLoader.load(Cache.class);

    storageFactories = new ArrayList<>();
    for(StorageFactory storageFactory:serviceLoader){
      storageFactories.add(storageFactory);
    }

    caches = new ArrayList<>();
    for(Cache cache:serviceCaches){
      caches.add(cache);
    }

    caches.forEach(layer -> layered.add(layer.getName()));
    storageFactories.forEach(storageFactory -> known.add(storageFactory.getName()));
  }

  public static StorageFactoryFactory getInstance() {
    return instance;
  }

  public List getKnownStorages() {
    return known;
  }

  public List getKnownLayers(){
    return layered;
  }

  @SuppressWarnings("java:S2293")
  @SneakyThrows
  @Nullable  StorageFactory create(@NotNull String name, @NotNull Map properties, @NotNull StorableFactory storableFactory,
      ExpiredStorableHandler expiredStorableHandler) {
    Optional first = storageFactories.stream().filter(storageFactoryProvider -> storageFactoryProvider.getName().equals(name)).findFirst();
    if (first.isPresent()) {
      logger.log(StorageLogMessages.FOUND_FACTORY, first.get().getClass().getName());
      StorageFactory found = first.get();
      Class clazz = (Class) found.getClass();
      Constructor[] constructors = (Constructor[]) clazz.getDeclaredConstructors();
      Constructor constructor = null;
      for (Constructor cstr : constructors) {
        if (cstr.getParameters().length == 3) {
          constructor = cstr;
          logger.log(StorageLogMessages.FOUND_CONSTRUCTOR, name);
          break;
        }
      }
      if (constructor != null) {
        return (StorageFactory) constructor.newInstance(properties, storableFactory, expiredStorableHandler);
      }
      else{
        logger.log(StorageLogMessages.NO_CONSTRUCTOR_FOUND, name);

      }
    }
    else {
      logger.log(StorageLogMessages.NO_MATCHING_FACTORY, name);
    }

    return null;
  }

  @SuppressWarnings("java:S2293")
  @SneakyThrows
  @NotNull  CacheLayer createCache(@NotNull String name, boolean enableWriteThrough, @NotNull Storage baseStore) {
    Optional first = caches.stream().filter(layer -> layer.getName().equals(name)).findFirst();
    if (first.isPresent()) {
      logger.log(StorageLogMessages.FOUND_CACHE_FACTORY, name);
      Cache found = first.get();
      Class clazz = (Class) found.getClass();
      Constructor[] constructors = (Constructor[]) clazz.getDeclaredConstructors();
      Constructor constructor = null;
      for (Constructor cstr : constructors) {
        if (cstr.getParameters().length == 1) {
          logger.log(StorageLogMessages.FOUND_CACHE_CONSTRUCTOR, name);
          constructor = cstr;
          break;
        }
      }
      if (constructor != null) {
        Cache cache = (Cache) constructor.newInstance(baseStore.getName());
        logger.log(StorageLogMessages.CREATED_NEW_CACHE_INSTANCE, name);
        return new CacheLayer(enableWriteThrough, cache, baseStore);
      }
    }
    logger.log(StorageLogMessages.NO_CACHE_FOUND, name);

    throw new IOException("Unknown layered storage declared");
  }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy