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

hope.kola.contract.converter.FeatureConverter Maven / Gradle / Ivy

There is a newer version: 1.1.2-RELEASE
Show newest version
package hope.kola.contract.converter;

import groovy.lang.GroovyShell;
import hope.kola.contract.Feature;
import hope.kola.contract.exception.FeatureParseException;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ObjectUtils;

@SuppressWarnings("Duplicates")
public class FeatureConverter {

  private static final Logger LOG = LoggerFactory.getLogger(FeatureConverter.class);
  private static final Pattern PACKAGE_PATTERN =
      Pattern.compile(".*package (.+?);.+?", Pattern.DOTALL);

  public static Collection convertAsCollection(File rootFolder, File dsl) {
    ClassLoader classLoader = FeatureConverter.class.getClassLoader();
    try {
      ClassLoader urlCl = updatedClassLoader(rootFolder, classLoader);
      Object object = toObject(urlCl, rootFolder, dsl);
      return listOfFeatures(dsl, object);
    } catch (FeatureParseException e) {
      throw e;
    } catch (Exception e) {
      LOG.error(
          "Exception occurred while trying to evaluate the feature at path [" + dsl.getPath() + "]",
          e);
      throw new FeatureParseException(e);
    } finally {
      Thread.currentThread().setContextClassLoader(classLoader);
    }
  }

  private static Collection listOfFeatures(File file, Object object) {
    if (object == null) {
      return Collections.emptyList();
    } else if (isACollectionOfFeatures(object)) {
      return withName(file, (Collection) object);
    } else if (!(object instanceof Feature)) {
      throw new FeatureParseException("Feature is not returning a Feature or list of Features");
    }
    return withName(file, Collections.singletonList((Feature) object));
  }

  private static boolean isACollectionOfFeatures(Object object) {
    return object instanceof Collection
        && ((Collection) object).stream().allMatch(it -> it instanceof Feature);
  }

  private static Collection withName(File file, Collection features) {
    AtomicInteger counter = new AtomicInteger(0);
    return features.stream()
        .peek(
            it -> {
              if (featureNameEmpty(it)) {
                it.name(defaultFeatureName(file, features, counter.get()));
              }
              counter.getAndIncrement();
            })
        .collect(Collectors.toList());
  }

  private static boolean featureNameEmpty(Feature it) {
    return it != null && ObjectUtils.isEmpty(it.getName());
  }

  /**
   * @param file - file with contracts
   * @param features - collection of contracts
   * @param counter - given contract index
   * @return the default contract name, resolved from file name, taking * into consideration also
   *     the index of contract (for multiple contracts * stored in a single file).
   */
  public static String defaultFeatureName(File file, Collection features, int counter) {
    int lastIndexOfDot = file.getName().lastIndexOf(".");
    String tillExtension = file.getName().substring(0, lastIndexOfDot);
    return tillExtension + (counter > 0 || features.size() > 1 ? "_" + counter : "");
  }

  public static Object toObject(ClassLoader cl, File rootFolder, File dsl) throws IOException {
    CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
    compilerConfiguration.setSourceEncoding("UTF-8");
    compilerConfiguration.setClasspathList(Collections.singletonList(rootFolder.getAbsolutePath()));
    return new GroovyShell(cl, compilerConfiguration).evaluate(dsl);
  }

  public static ClassLoader updatedClassLoader(File rootFolder, ClassLoader classLoader) {
    ClassLoader urlCl;
    try {
      urlCl =
          URLClassLoader.newInstance(
              Collections.singletonList(rootFolder.toURI().toURL()).toArray(new URL[0]),
              classLoader);
    } catch (MalformedURLException e) {
      LOG.error(
          "Exception occurred while trying to construct the URL from the root folder at path ["
              + rootFolder.getPath()
              + "]",
          e);
      throw new FeatureParseException(e);
    }
    updateTheThreadClassLoader(urlCl);
    return urlCl;
  }

  private static void updateTheThreadClassLoader(ClassLoader urlCl) {
    Thread.currentThread().setContextClassLoader(urlCl);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy