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

no.mnemonic.commons.container.providers.SpringXmlBeanProvider Maven / Gradle / Ivy

package no.mnemonic.commons.container.providers;

import no.mnemonic.commons.component.ComponentException;
import no.mnemonic.commons.utilities.StreamUtils;
import no.mnemonic.commons.utilities.collections.ListUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

import java.io.*;
import java.util.*;

public class SpringXmlBeanProvider implements BeanProvider {


  private final List inputs;
  private final List inputStreams;
  private final Properties properties;
  private final ClassLoader classLoader;

  private ApplicationContext applicationContext;
  private BeanFactory parent;

  private SpringXmlBeanProvider(List inputs, List inputStreams, Properties properties, ClassLoader classLoader) {
    this.inputs = inputs;
    this.inputStreams = inputStreams;
    this.properties = properties;
    this.classLoader = classLoader;
  }

  @Override
  public  Optional getBean(Class ofType) {
    try {
      return Optional.of(resolveBeans().getBean(ofType));
    } catch (Exception e) {
      return Optional.empty();
    }
  }

  @Override
  public  Map getBeans(Class ofType) {
    return resolveBeans().getBeansOfType(ofType);
  }

  @Override
  public Map getBeans() {
    return resolveBeans().getBeansOfType(Object.class);
  }

  private ApplicationContext resolveBeans() {

    if (applicationContext != null) return applicationContext;

    ApplicationContext parentCtx;
    if (parent == null) {
      parentCtx = null;
    } else if (parent instanceof ApplicationContext) {
      parentCtx = (ApplicationContext) parent;
    } else if (parent instanceof DefaultListableBeanFactory) {
      parentCtx = new GenericApplicationContext((DefaultListableBeanFactory) parent);
    } else {
      throw new RuntimeException("Cannot set up a new application context pointing to parent beanfactory of type " + parent.getClass());
    }

    //prepare factory
    List res = fetchResources();
    GenericApplicationContext ctx = new GenericApplicationContext(parentCtx);

    // load resources
    for (Resource r : res) {
      XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(ctx);
      reader.setBeanClassLoader(classLoader);
      reader.loadBeanDefinitions(r);
    }

    // parse properties
    if (properties != null) {
      PropertyPlaceholderConfigurer propCfg = new PropertyPlaceholderConfigurer();
      propCfg.setProperties(properties);
      ctx.addBeanFactoryPostProcessor(propCfg);
    }

    ctx.refresh();

    // instansiate singletons
    applicationContext = ctx;
    return applicationContext;
  }

  public static Builder builder() {
    return new Builder();
  }

  public String toString() {
    return "[SpringXmlBeanProvider inputs=" + inputs + " inputStreams=" + inputStreams + " classLoader="
            + classLoader + " properties=" + properties + "]";
  }

  private List fetchResources() throws ComponentException {
    try {
      //create resourcelist
      List r = new ArrayList<>();
      //if the input string points to an existing file, use filesystemresource
      //else use classpathresource
      for (String s : inputs) {
        File f = new File(s);
        if (f.exists()) {
          r.add(new FileSystemResource(f));
        } else {
          r.add(new ClassPathResource(s));
        }
      }
      //attempt to load each configured inputstream
      for (InputStream is : inputStreams) {
        File f = File.createTempFile("XmlBeanProvider", "resource");
        OutputStream fos = new FileOutputStream(f);
        StreamUtils.writeUntilEOF(is, fos);
        fos.close();
        r.add(new FileSystemResource(f));
      }
      return r;
    } catch (IOException e) {
      throw new ComponentException(e);
    }
  }

  public static class Builder {

    private List inputs = new ArrayList<>();
    private List inputStreams = new ArrayList<>();
    private Properties properties = System.getProperties();
    private ClassLoader classLoader = ClassLoader.getSystemClassLoader();

    private Builder() {
    }

    public SpringXmlBeanProvider build() {
      return new SpringXmlBeanProvider(inputs, inputStreams, properties, classLoader);
    }

    public Builder addInput(String descriptorName) {
      this.inputs = ListUtils.addToList(this.inputs, descriptorName);
      return this;
    }

    public Builder addInputStream(InputStream is) {
      this.inputStreams = ListUtils.addToList(this.inputStreams, is);
      return this;
    }

    public Builder setInputs(List inputs) {
      this.inputs = inputs;
      return this;
    }

    public Builder setInputStreams(List inputStreams) {
      this.inputStreams = inputStreams;
      return this;
    }

    public Builder setProperties(Properties properties) {
      this.properties = properties;
      return this;
    }

    public Builder setClassLoader(ClassLoader classLoader) {
      this.classLoader = classLoader;
      return this;
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy