@Programmatic
  @Override
  public <T> Set<Class<? extends T>> findSubTypesOfClasses(Class<T> type) {
    Vfs.setDefaultURLTypes(getUrlTypes());

    final Reflections reflections =
        new Reflections(
            ClasspathHelper.forClassLoader(Thread.currentThread().getContextClassLoader()),
            ClasspathHelper.forClass(Object.class),
            new SubTypesScanner(false));
    return reflections.getSubTypesOf(type);
  }
  public static Set<Class<?>> getTypesAnnotatedWith(
      Class<? extends Annotation> annotation, ClassLoader... classLoaders) throws Exception {

    Set<Class<?>> implementations;
    implementations = (Set<Class<?>>) classesCache.get(annotation);

    ConfigurationBuilder cb =
        new ConfigurationBuilder()
            .setUrls(ClasspathHelper.forPackage("es.caib"))
            .setScanners(new SubTypesScanner(), new TypeAnnotationsScanner());

    if (classLoaders != null && classLoaders.length != 0) {
      cb.addClassLoaders(classLoaders);
    }

    if (implementations == null) {
      implementations = new HashSet<Class<?>>();
      Reflections ref = new Reflections(cb);

      Set<Class<?>> tmp = ref.getTypesAnnotatedWith(annotation);
      implementations.addAll(tmp);
      classesCache.put(annotation, implementations);
    }

    return implementations;
  }
  private void loadExtensionsFromClassloaders(
      Map<String, DefaultCoreExtension> extensions, DefaultCoreExtensionRepository repository) {
    Set<URL> mavenURLs = ClasspathHelper.forPackage(MAVENPACKAGE);

    ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
    configurationBuilder.setScanners(new ResourcesScanner());
    configurationBuilder.setUrls(mavenURLs);
    configurationBuilder.filterInputsBy(
        new FilterBuilder.Include(FilterBuilder.prefix(MAVENPACKAGE)));

    Reflections reflections = new Reflections(configurationBuilder);

    Set<String> descriptors = reflections.getResources(Predicates.equalTo("pom.xml"));

    for (String descriptor : descriptors) {
      URL descriptorUrl = getClass().getClassLoader().getResource(descriptor);

      try {
        DefaultCoreExtension coreExtension = parseMavenPom(descriptorUrl, repository);

        extensions.put(coreExtension.getId().getId(), coreExtension);
      } catch (Exception e) {
        this.logger.warn("Failed to pase extension descriptor [{}]", descriptorUrl, e);
      }
    }

    // Try to find more

    guess(extensions, repository);
  }
 private Iterator<Resource> getFilesFromParams() throws IOException {
   System.err.printf(
       "%s system property not specified, using 'dir'" + " parameter from configuration file\n",
       DIR_PROPERTY);
   String resource = (String) getConfigParameterValue("dir");
   String suffix = (String) getConfigParameterValue("suffix");
   if (resource != null) {
     System.err.printf("Reading files from classpath directory: %s\n", resource);
     Reflections reflections =
         new Reflections(
             new ConfigurationBuilder()
                 .setUrls(ClasspathHelper.forPackage(""))
                 .setScanners(new ResourcesScanner()));
     Set<String> files = reflections.getResources(Pattern.compile(".*\\." + suffix));
     Collection<Resource> resources =
         Collections2.transform(files, new StringToResourceFunction("/"));
     final Pattern p = Pattern.compile("^" + resource);
     Collection<Resource> filtered =
         Collections2.filter(
             resources,
             new Predicate<Resource>() {
               @Override
               public boolean apply(Resource input) {
                 Matcher m = p.matcher(input.name);
                 return m.find();
               }
             });
     return filtered.iterator();
   } else {
     throw new IOException(String.format("Parameter 'dir' must be specified"));
   }
 }
  /*
   * Scan the classpath looking for JAX-RS Application sub-classes
   */
  private static Set<Class<? extends Application>> findJaxrsApplicationClasses() {
    logger.info("Scanning classpath to find JAX-RS Application classes");

    final Collection<URL> systemPropertyURLs = ClasspathHelper.forJavaClassPath();
    final Collection<URL> classLoaderURLs = ClasspathHelper.forClassLoader();

    Set<URL> classpathURLs = new HashSet<URL>();

    copyValidClasspathEntries(systemPropertyURLs, classpathURLs);
    copyValidClasspathEntries(classLoaderURLs, classpathURLs);

    logger.debug("Classpath URLs to be scanned: " + classpathURLs);

    Reflections reflections = new Reflections(classpathURLs, new SubTypesScanner());

    return reflections.getSubTypesOf(Application.class);
  }
  @Override
  public DioritePlugin loadPlugin(final File file) throws PluginException {
    try {
      final PluginClassLoader classLoader = new PluginClassLoader(file);

      final ConfigurationBuilder config = new ConfigurationBuilder();
      config.setClassLoaders(new PluginClassLoader[] {classLoader});
      config.setUrls(ClasspathHelper.forClassLoader(classLoader));

      final Reflections ref = new Reflections(config);
      final Set<Class<?>> annotated = ref.getTypesAnnotatedWith(Plugin.class);
      if (annotated.isEmpty()) {
        throw new PluginException("Plugin annotation doesn't found!");
      }
      if (annotated.size() > 1) {
        throw new PluginException("Plugin has more than one main class!");
      }

      final Class<?> mainClass = annotated.iterator().next();

      if (!DioritePlugin.class.isAssignableFrom(mainClass)) {
        throw new PluginException("Main class must extend PluginMainClass!");
      }

      final DioritePlugin dioritePlugin = (DioritePlugin) mainClass.newInstance();
      final Plugin pluginDescription = mainClass.getAnnotation(Plugin.class);

      if (ServerImpl.getInstance().getPluginManager().getPlugin(pluginDescription.name()) != null) {
        throw new PluginException("Plugin " + pluginDescription.name() + " is arleady loaded!");
      }

      dioritePlugin.init(
          classLoader,
          this,
          dioritePlugin,
          pluginDescription.name(),
          pluginDescription.version(),
          pluginDescription.author(),
          pluginDescription.description(),
          pluginDescription.website());
      System.out.println(
          "Loading "
              + pluginDescription.name()
              + " v"
              + pluginDescription.version()
              + " by "
              + pluginDescription.author()
              + " from file "
              + file.getName());
      dioritePlugin.onLoad();

      return dioritePlugin;
    } catch (final InstantiationException | IllegalAccessException | MalformedURLException e) {
      throw new PluginException("Exception while loading plugin from file " + file.getName(), e);
    }
  }
Beispiel #7
0
  /**
   * Create a package inspector that looks for the specified type.
   *
   * @param classType the type of class to look for in the package
   */
  public PackageInspector(Class<ClassType> classType, String packageName) {
    Set<URL> classPath = ClasspathHelper.forPackage(packageName);

    ConfigurationBuilder config = new ConfigurationBuilder();
    config.setUrls(classPath);
    config.setScanners(new SubTypesScanner());

    this.reflections = new Reflections(config);
    this.classType = classType;
    this.packageName = packageName;
  }
Beispiel #8
0
  /**
   * collect saved Reflections resources from all urls that contains the given packagePrefix and
   * matches the given resourceNameFilter and de-serializes them using the default serializer {@link
   * org.reflections.serializers.XmlSerializer} or using the optionally supplied optionalSerializer
   *
   * <p>it is preferred to use a designated resource prefix (for example META-INF/reflections but
   * not just META-INF), so that relevant urls could be found much faster
   *
   * @param optionalSerializer - optionally supply one serializer instance. if not specified or
   *     null, {@link org.reflections.serializers.XmlSerializer} will be used
   */
  public static Reflections collect(
      final String packagePrefix,
      final Predicate<String> resourceNameFilter,
      @Nullable Serializer... optionalSerializer) {
    Serializer serializer =
        optionalSerializer != null && optionalSerializer.length == 1
            ? optionalSerializer[0]
            : new XmlSerializer();

    Collection<URL> urls = ClasspathHelper.forPackage(packagePrefix);
    if (urls.isEmpty()) return null;
    long start = System.currentTimeMillis();
    final Reflections reflections = new Reflections();
    Iterable<Vfs.File> files = Vfs.findFiles(urls, packagePrefix, resourceNameFilter);
    for (final Vfs.File file : files) {
      InputStream inputStream = null;
      try {
        inputStream = file.openInputStream();
        reflections.merge(serializer.read(inputStream));
      } catch (IOException e) {
        throw new ReflectionsException("could not merge " + file, e);
      } finally {
        close(inputStream);
      }
    }

    if (log != null) {
      Store store = reflections.getStore();
      int keys = 0;
      int values = 0;
      for (String index : store.keySet()) {
        keys += store.get(index).keySet().size();
        values += store.get(index).size();
      }

      log.info(
          format(
              "Reflections took %d ms to collect %d url%s, producing %d keys and %d values [%s]",
              System.currentTimeMillis() - start,
              urls.size(),
              urls.size() > 1 ? "s" : "",
              keys,
              values,
              Joiner.on(", ").join(urls)));
    }
    return reflections;
  }
    public ClassDiscoveryImpl(String pkg) {
      this.pkg = pkg;

      configuration = new ConfigurationBuilder();
      final Predicate<String> filter = new FilterBuilder.Include(FilterBuilder.prefix(pkg));

      configuration.setUrls(ClasspathHelper.forPackage(pkg));
      configuration.filterInputsBy(filter);
      configuration.setScanners(new TypeAnnotationsScanner().filterResultsBy(filter));

      store = new Store(configuration);
      for (Scanner scanner : configuration.getScanners()) {
        scanner.setConfiguration(configuration);
        scanner.setStore(store.get(scanner));
      }

      index();
    }
Beispiel #10
0
  /** 通过扫描,获取反射对象 */
  private Reflections getReflection(List<String> packNameList) {

    //
    // filter
    //
    FilterBuilder filterBuilder = new FilterBuilder().includePackage(Constants.DISCONF_PACK_NAME);

    for (String packName : packNameList) {
      filterBuilder = filterBuilder.includePackage(packName);
    }
    Predicate<String> filter = filterBuilder;

    //
    // urls
    //
    Collection<URL> urlTotals = new ArrayList<URL>();
    for (String packName : packNameList) {
      Set<URL> urls = ClasspathHelper.forPackage(packName);
      urlTotals.addAll(urls);
    }

    //
    Reflections reflections =
        new Reflections(
            new ConfigurationBuilder()
                .filterInputsBy(filter)
                .setScanners(
                    new SubTypesScanner().filterResultsBy(filter),
                    new TypeAnnotationsScanner().filterResultsBy(filter),
                    new FieldAnnotationsScanner().filterResultsBy(filter),
                    new MethodAnnotationsScanner().filterResultsBy(filter),
                    new MethodParameterScanner())
                .setUrls(urlTotals));

    return reflections;
  }
  private void guess(
      Map<String, DefaultCoreExtension> extensions, DefaultCoreExtensionRepository repository) {
    Set<ExtensionDependency> dependencies = new HashSet<ExtensionDependency>();

    for (DefaultCoreExtension coreExtension : extensions.values()) {
      for (ExtensionDependency dependency : coreExtension.getDependencies()) {
        dependencies.add(dependency);
      }
    }

    // Normalize and guess

    Map<String, Object[]> fileNames = new HashMap<String, Object[]>();
    Map<String, Object[]> guessedArtefacts = new HashMap<String, Object[]>();
    Set<URL> urls = ClasspathHelper.forClassLoader();

    for (URL url : urls) {
      try {
        String path = url.toURI().getPath();
        String filename = path.substring(path.lastIndexOf('/') + 1);
        String type = null;

        int extIndex = filename.lastIndexOf('.');
        if (extIndex != -1) {
          type = filename.substring(extIndex + 1);
          filename = filename.substring(0, extIndex);
        }

        int index;
        if (!filename.endsWith(SNAPSHOTSUFFIX)) {
          index = filename.lastIndexOf('-');
        } else {
          index = filename.lastIndexOf('-', filename.length() - SNAPSHOTSUFFIX.length());
        }

        if (index != -1) {
          fileNames.put(filename, new Object[] {url});

          String artefactname = filename.substring(0, index);
          String version = filename.substring(index + 1);

          guessedArtefacts.put(artefactname, new Object[] {version, url, type});
        }
      } catch (Exception e) {
        this.logger.warn("Failed to parse resource name [" + url + "]", e);
      }
    }

    // Try to resolve version no easy to find from the pom.xml
    try {
      for (DefaultCoreExtension coreExtension : extensions.values()) {
        String artifactId = getArtifactId(coreExtension);

        Object[] artefact = guessedArtefacts.get(artifactId);

        if (artefact != null) {
          if (coreExtension.getId().getVersion().getValue().charAt(0) == '$') {
            coreExtension.setId(
                new ExtensionId(coreExtension.getId().getId(), (String) artefact[0]));
            coreExtension.setGuessed(true);
          }

          if (coreExtension.getType().charAt(0) == '$') {
            coreExtension.setType((String) artefact[2]);
            coreExtension.setGuessed(true);
          }
        }
      }

      // Add dependencies that does not provide proper pom.xml resource and can't be found in the
      // classpath
      for (ExtensionDependency extensionDependency : dependencies) {
        Dependency dependency =
            (Dependency)
                extensionDependency.getProperty(MavenCoreExtensionDependency.PKEY_MAVEN_DEPENDENCY);

        if (dependency == null) {
          dependency =
              toDependency(
                  extensionDependency.getId(),
                  extensionDependency.getVersionConstraint().getValue(),
                  null);
        }

        String dependencyId = dependency.getGroupId() + ':' + dependency.getArtifactId();

        DefaultCoreExtension coreExtension = extensions.get(dependencyId);
        if (coreExtension == null) {
          String dependencyFileName = dependency.getArtifactId() + '-' + dependency.getVersion();
          if (dependency.getClassifier() != null) {
            dependencyFileName += '-' + dependency.getClassifier();
            dependencyId += ':' + dependency.getClassifier();
          }

          Object[] filenameArtifact = fileNames.get(dependencyFileName);
          Object[] guessedArtefact = guessedArtefacts.get(dependency.getArtifactId());

          if (filenameArtifact != null) {
            coreExtension =
                new DefaultCoreExtension(
                    repository,
                    (URL) filenameArtifact[0],
                    new ExtensionId(dependencyId, dependency.getVersion()),
                    packagingToType(dependency.getType()));
            coreExtension.setGuessed(true);
          } else if (guessedArtefact != null) {
            coreExtension =
                new DefaultCoreExtension(
                    repository,
                    (URL) guessedArtefact[1],
                    new ExtensionId(dependencyId, (String) guessedArtefact[0]),
                    packagingToType(dependency.getType()));
            coreExtension.setGuessed(true);
          }

          if (coreExtension != null) {
            extensions.put(dependencyId, coreExtension);
          }
        }
      }
    } catch (Exception e) {
      this.logger.warn("Failed to guess extra information about some extensions", e);
    }
  }
public abstract class AbstractRemoteSerializationTest extends JbpmJUnitBaseTestCase {

  protected static final Logger logger =
      LoggerFactory.getLogger(AbstractRemoteSerializationTest.class);

  protected enum TestType {
    JAXB,
    JSON,
    YAML;
  }

  public abstract TestType getType();

  public abstract void addClassesToSerializationProvider(Class<?>... extraClass);

  public abstract <T> T testRoundTrip(T in) throws Exception;

  private static Reflections reflections =
      new Reflections(
          ClasspathHelper.forPackage("org.kie.services.client"),
          ClasspathHelper.forPackage("org.kie.remote"),
          new TypeAnnotationsScanner(),
          new SubTypesScanner());

  // TESTS

  /*
   * Tests
   */

  @Test
  public void jaxbClassesTest() throws Exception {
    Assume.assumeTrue(TestType.JAXB.equals(getType()));

    Set<Class<?>> jaxbClasses = reflections.getTypesAnnotatedWith(XmlRootElement.class);

    assertTrue("Not enough classes found! [" + jaxbClasses.size() + "]", jaxbClasses.size() > 20);

    String className = null;
    try {
      for (Class<?> jaxbClass : jaxbClasses) {
        if (jaxbClass.getDeclaringClass() != null
            && jaxbClass.getDeclaringClass().getSimpleName().endsWith("Test")) {
          continue;
        }
        className = jaxbClass.getName();
        Constructor<?> construct = jaxbClass.getConstructor(new Class[] {});
        Object jaxbInst = construct.newInstance(new Object[] {});
        testRoundTrip(jaxbInst);
      }
    } catch (Exception e) {
      e.printStackTrace();
      fail(className + ": " + e.getClass().getSimpleName() + " [" + e.getMessage() + "]");
    }
  }

  @Test
  public void genericResponseTest() throws Exception {
    JaxbGenericResponse resp = new JaxbGenericResponse();
    resp.setMessage("error");
    resp.setStatus(JaxbRequestStatus.SUCCESS);
    resp.setUrl("http://here");

    testRoundTrip(resp);
  }

  @Test
  public void exceptionTest() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    JaxbExceptionResponse resp = new JaxbExceptionResponse();
    resp.setMessage("error");
    resp.setStatus(JaxbRequestStatus.SUCCESS);
    resp.setUrl("http://here");

    RuntimeException re = new RuntimeException();
    resp.setCause(re);

    testRoundTrip(resp);
  }

  @Test
  public void variablesResponseTest() throws Exception {
    JaxbVariablesResponse resp = new JaxbVariablesResponse();

    testRoundTrip(resp);

    Map<String, String> vars = new HashMap<String, String>();
    vars.put("one", "two");
    resp.setVariables(vars);

    testRoundTrip(resp);
  }

  @Test
  public void historyLogListTest() throws Exception {
    JaxbHistoryLogList resp = new JaxbHistoryLogList();

    testRoundTrip(resp);

    // vLog
    org.jbpm.process.audit.VariableInstanceLog vLog =
        new org.jbpm.process.audit.VariableInstanceLog(
            23, "process", "varInst", "var", "two", "one");
    vLog.setExternalId("domain");
    Field dateField = org.jbpm.process.audit.VariableInstanceLog.class.getDeclaredField("date");
    dateField.setAccessible(true);
    dateField.set(vLog, new Date());
    Field idField = org.jbpm.process.audit.VariableInstanceLog.class.getDeclaredField("id");
    idField.setAccessible(true);
    idField.set(vLog, 32l);
    resp.getHistoryLogList().add(new JaxbVariableInstanceLog(vLog));

    // pLog
    org.jbpm.process.audit.ProcessInstanceLog pLog =
        new org.jbpm.process.audit.ProcessInstanceLog(23, "process");
    pLog.setDuration(2000l);
    pLog.setEnd(new Date());
    pLog.setExternalId("domain");
    pLog.setIdentity("id");
    pLog.setOutcome("error");
    pLog.setParentProcessInstanceId(42);
    pLog.setProcessName("name");
    pLog.setProcessVersion("1-SNAP");
    pLog.setStatus(2);
    idField = org.jbpm.process.audit.ProcessInstanceLog.class.getDeclaredField("id");
    idField.setAccessible(true);
    idField.set(pLog, 32l);
    resp.getHistoryLogList().add(new JaxbProcessInstanceLog(pLog));

    // nLog
    org.jbpm.process.audit.NodeInstanceLog nLog =
        new org.jbpm.process.audit.NodeInstanceLog(0, 23, "process", "nodeInst", "node", "wally");
    idField = org.jbpm.process.audit.NodeInstanceLog.class.getDeclaredField("id");
    idField.setAccessible(true);
    idField.set(nLog, 32l);
    dateField = org.jbpm.process.audit.NodeInstanceLog.class.getDeclaredField("date");
    dateField.setAccessible(true);
    dateField.set(nLog, new Date());
    nLog.setNodeType("type");
    nLog.setWorkItemId(88l);
    nLog.setConnection("connex");
    nLog.setExternalId("domain");
    resp.getHistoryLogList().add(new JaxbNodeInstanceLog(nLog));

    testRoundTrip(resp);
  }

  @Test
  public void processInstanceWithVariablesTest() throws Exception {

    this.setupDataSource = true;
    this.sessionPersistence = true;
    super.setUp();

    RuntimeEngine runtimeEngine =
        createRuntimeManager("BPMN2-StringStructureRef.bpmn2").getRuntimeEngine(null);
    KieSession ksession = runtimeEngine.getKieSession();

    Map<String, Object> params = new HashMap<String, Object>();
    String val = "initial-val";
    params.put("test", val);
    ProcessInstance processInstance = ksession.startProcess("StructureRef");
    assertTrue(processInstance.getState() == ProcessInstance.STATE_ACTIVE);

    Map<String, Object> res = new HashMap<String, Object>();
    res.put("testHT", "test value");
    // ksession.getWorkItemManager().completeWorkItem(workItemHandler.getWorkItem().getId(),
    // res);

    Map<String, String> map = new HashMap<String, String>();
    map.put("test", "initial-val");

    JaxbProcessInstanceWithVariablesResponse jpiwvr =
        new JaxbProcessInstanceWithVariablesResponse(processInstance, map);
    testRoundTrip(jpiwvr);

    JaxbProcessInstanceListResponse jpilp = new JaxbProcessInstanceListResponse();
    List<ProcessInstance> procInstList = new ArrayList<ProcessInstance>();
    procInstList.add(new JaxbProcessInstanceResponse(processInstance));
    jpilp.setResult(procInstList);
    testRoundTrip(jpilp);

    super.tearDown();
    this.setupDataSource = false;
    this.sessionPersistence = false;
  }

  @Test
  public void workItemObjectTest() throws Exception {
    // Don't run with YAML?
    Assume.assumeFalse(getType().equals(TestType.YAML));

    JaxbWorkItemResponse workitemObject = new JaxbWorkItemResponse();
    workitemObject.setId(35l);
    workitemObject.setName("Clau");
    workitemObject.setState(0);
    workitemObject.setProcessInstanceId(1l);
    Map<String, Object> params = new HashMap<String, Object>();
    params.put("test", "driving");
    workitemObject.setParameters(params);
    JaxbWorkItemResponse roundTripWorkItem = testRoundTrip(workitemObject);
    ComparePair.compareObjectsViaFields(workitemObject, roundTripWorkItem);
  }

  @Test
  // JBPM-4170
  public void nodeInstanceLogNpeTest() throws Exception {
    org.jbpm.process.audit.NodeInstanceLog nodeLog = new org.jbpm.process.audit.NodeInstanceLog();
    JaxbNodeInstanceLog jaxbNodeLog = new JaxbNodeInstanceLog(nodeLog);
    testRoundTrip(jaxbNodeLog);
  }

  @Test
  public void deploymentObjectsTest() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    // for test at end, fill during test
    JaxbDeploymentUnitList depUnitList = new JaxbDeploymentUnitList();

    // dep jobs
    JaxbDeploymentJobResult jaxbJob = new JaxbDeploymentJobResult();
    testRoundTrip(jaxbJob);

    // complex dep jobs
    KModuleDeploymentUnit kDepUnit =
        new KModuleDeploymentUnit("org", "jar", "1.0", "kbase", "ksession");
    kDepUnit.setStrategy(RuntimeStrategy.PER_PROCESS_INSTANCE);

    JaxbDeploymentUnit depUnit =
        new JaxbDeploymentUnit(
            kDepUnit.getGroupId(), kDepUnit.getArtifactId(), kDepUnit.getArtifactId());
    depUnit.setKbaseName(kDepUnit.getKbaseName());
    depUnit.setKsessionName(kDepUnit.getKsessionName());
    depUnit.setStrategy(kDepUnit.getStrategy());
    depUnit.setStatus(JaxbDeploymentStatus.NONEXISTENT);
    depUnitList.getDeploymentUnitList().add(depUnit);

    jaxbJob = new JaxbDeploymentJobResult(null, "test", depUnit, "deploy");
    jaxbJob.setIdentifier(23L);
    jaxbJob.setSuccess(false);
    JaxbDeploymentJobResult copyJaxbJob = testRoundTrip(jaxbJob);
    ComparePair.compareObjectsViaFields(jaxbJob, copyJaxbJob, "jobId", "identifier");

    depUnit = new JaxbDeploymentUnit("g", "a", "v");
    depUnit.setKbaseName("kbase");
    depUnit.setKsessionName("ksession");
    depUnit.setStatus(JaxbDeploymentStatus.DEPLOY_FAILED);
    depUnit.setStrategy(RuntimeStrategy.PER_PROCESS_INSTANCE);
    depUnitList.getDeploymentUnitList().add(depUnit);

    JaxbDeploymentUnit copyDepUnit = testRoundTrip(depUnit);

    ComparePair.compareObjectsViaFields(depUnit, copyDepUnit, "identifier");

    JaxbDeploymentJobResult depJob =
        new JaxbDeploymentJobResult(null, "testing stuff", copyDepUnit, "test");
    depJob.setSuccess(true);
    JaxbDeploymentJobResult copyDepJob = testRoundTrip(depJob);

    ComparePair.compareObjectsViaFields(copyDepJob, depJob, "jobId", "identifier");

    JaxbDeploymentUnitList roundTripUnitList = testRoundTrip(depUnitList);
    ComparePair.compareObjectsViaFields(
        depUnitList.getDeploymentUnitList().get(0),
        roundTripUnitList.getDeploymentUnitList().get(0),
        "jobId",
        "identifier");
  }

  @Test
  public void processInstanceLogTest() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    org.jbpm.process.audit.ProcessInstanceLog origLog =
        new org.jbpm.process.audit.ProcessInstanceLog(54, "org.hospital.patient.triage");
    origLog.setDuration(65l);
    origLog.setDuration(234l);
    origLog.setEnd(new Date((new Date()).getTime() + 1000));
    origLog.setExternalId("testDomainId");
    origLog.setIdentity("identityNotMemory");
    origLog.setProcessInstanceDescription("What a process, say!");

    // nullable
    origLog.setStatus(2);
    origLog.setOutcome("descriptiveErrorCodeOfAnError");
    origLog.setParentProcessInstanceId(65l);

    origLog.setProcessName("org.process.not.technical");
    origLog.setProcessVersion("v3.14");

    JaxbProcessInstanceLog xmlLog = new JaxbProcessInstanceLog(origLog);
    xmlLog.setCommandName("test-cmd");
    xmlLog.setIndex(2);
    JaxbProcessInstanceLog newXmlLog = testRoundTrip(xmlLog);
    ComparePair.compareObjectsViaFields(xmlLog, newXmlLog, "id");

    ProcessInstanceLog newLog = newXmlLog.getResult();
    ProcessInstanceLog origCmpLog = origLog;
    assertEquals(origLog.getExternalId(), newLog.getExternalId());
    assertEquals(origCmpLog.getIdentity(), newLog.getIdentity());
    assertEquals(origCmpLog.getOutcome(), newLog.getOutcome());
    assertEquals(origCmpLog.getProcessId(), newLog.getProcessId());
    assertEquals(origCmpLog.getProcessName(), newLog.getProcessName());
    assertEquals(origCmpLog.getProcessVersion(), newLog.getProcessVersion());
    assertEquals(origCmpLog.getDuration(), newLog.getDuration());
    assertEquals(origCmpLog.getEnd(), newLog.getEnd());
    assertEquals(origCmpLog.getParentProcessInstanceId(), newLog.getParentProcessInstanceId());
    assertEquals(origCmpLog.getProcessInstanceId(), newLog.getProcessInstanceId());
    assertEquals(origCmpLog.getStart(), newLog.getStart());
    assertEquals(origCmpLog.getStatus(), newLog.getStatus());
  }

  @Test
  public void processInstanceLogNillable() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    org.jbpm.process.audit.ProcessInstanceLog origLog =
        new org.jbpm.process.audit.ProcessInstanceLog(54, "org.hospital.patient.triage");
    origLog.setDuration(65l);
    origLog.setEnd(new Date((new Date()).getTime() + 1000));
    origLog.setExternalId("testDomainId");
    origLog.setIdentity("identityNotMemory");

    // nullable/nillable
    // origLog.setStatus(2);
    // origLog.setOutcome("descriptiveErrorCodeOfAnError");
    // origLog.setParentProcessInstanceId(65l);

    origLog.setProcessName("org.process.not.technical");
    origLog.setProcessVersion("v3.14");

    JaxbProcessInstanceLog xmlLog = new JaxbProcessInstanceLog(origLog);
    JaxbProcessInstanceLog newXmlLog = testRoundTrip(xmlLog);

    assertEquals(xmlLog.getProcessInstanceId(), newXmlLog.getProcessInstanceId());
    assertEquals(xmlLog.getProcessId(), newXmlLog.getProcessId());

    assertEquals(xmlLog.getDuration(), newXmlLog.getDuration());
    assertEquals(xmlLog.getEnd(), newXmlLog.getEnd());
    assertEquals(xmlLog.getExternalId(), newXmlLog.getExternalId());
    assertEquals(xmlLog.getIdentity(), newXmlLog.getIdentity());

    assertEquals(xmlLog.getStatus(), newXmlLog.getStatus());
    assertEquals(xmlLog.getOutcome(), newXmlLog.getOutcome());
    assertEquals(xmlLog.getParentProcessInstanceId(), newXmlLog.getParentProcessInstanceId());

    assertEquals(xmlLog.getProcessName(), newXmlLog.getProcessName());
    assertEquals(xmlLog.getProcessVersion(), newXmlLog.getProcessVersion());
  }

  @Test
  public void nodeInstanceLogTest() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    int type = 0;
    long processInstanceId = 23;
    String processId = "org.hospital.doctor.review";
    String nodeInstanceId = "1-1";
    String nodeId = "1";
    String nodeName = "notification";

    org.jbpm.process.audit.NodeInstanceLog origLog =
        new org.jbpm.process.audit.NodeInstanceLog(
            type, processInstanceId,
            processId, nodeInstanceId,
            nodeId, nodeName);

    origLog.setWorkItemId(78l);
    origLog.setConnection("link");
    origLog.setExternalId("not-internal-num");
    origLog.setNodeType("the-sort-of-point");

    JaxbNodeInstanceLog xmlLog = new JaxbNodeInstanceLog(origLog);
    xmlLog.setCommandName("test-cmd");
    xmlLog.setIndex(2);
    xmlLog.setId(2l);
    JaxbNodeInstanceLog newXmlLog = testRoundTrip(xmlLog);
    ComparePair.compareOrig(xmlLog, newXmlLog, JaxbNodeInstanceLog.class);

    NodeInstanceLog newLog = newXmlLog.getResult();
    ComparePair.compareOrig(origLog, newLog, NodeInstanceLog.class);
  }

  @Test
  public void variableInstanceLogTest() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    long processInstanceId = 23;
    String processId = "org.hospital.intern.rounds";
    String variableInstanceId = "patientNum-1";
    String variableId = "patientNum";
    String value = "33";
    String oldValue = "32";

    org.jbpm.process.audit.VariableInstanceLog origLog =
        new org.jbpm.process.audit.VariableInstanceLog(
            processInstanceId, processId, variableInstanceId, variableId, value, oldValue);

    origLog.setExternalId("outside-identity-representation");
    origLog.setOldValue("previous-data-that-this-variable-contains");
    origLog.setValue("the-new-data-that-has-been-put-in-this-variable");
    origLog.setVariableId("shortend-representation-of-this-representation");
    origLog.setVariableInstanceId("id-instance-variable");

    JaxbVariableInstanceLog xmlLog = new JaxbVariableInstanceLog(origLog);
    xmlLog.setCommandName("test-cmd");
    xmlLog.setIndex(2);
    JaxbVariableInstanceLog newXmlLog = testRoundTrip(xmlLog);
    ComparePair.compareObjectsViaFields(xmlLog, newXmlLog, "id");

    VariableInstanceLog newLog = newXmlLog.getResult();
    ComparePair.compareOrig(origLog, newLog, VariableInstanceLog.class);
  }

  @Test
  public void processIdAndProcessDefinitionTest() throws Exception {
    // JaxbProcessDefinition
    ProcessAssetDesc assetDesc =
        new ProcessAssetDesc(
            "org.test.proc.id",
            "The Name Of The Process",
            "1.999.23.Final",
            "org.test.proc",
            "RuleFlow",
            KnowledgeType.PROCESS.toString(),
            "org.test.proc",
            "org.test.proc:procs:1.999.Final");

    JaxbProcessDefinition jaxbProcDef = new JaxbProcessDefinition();
    jaxbProcDef.setDeploymentId(assetDesc.getDeploymentId());
    jaxbProcDef.setId(assetDesc.getId());
    jaxbProcDef.setName(assetDesc.getName());
    jaxbProcDef.setPackageName(assetDesc.getPackageName());
    jaxbProcDef.setVersion(assetDesc.getVersion());
    Map<String, String> forms = new HashMap<String, String>();
    forms.put("locationForm", "GPS: street: post code: city: state: land: planet: universe: ");
    jaxbProcDef.setForms(forms);

    JaxbProcessDefinition copyJaxbProcDef = testRoundTrip(jaxbProcDef);
    ComparePair.compareObjectsViaFields(jaxbProcDef, copyJaxbProcDef);
  }

  @Test
  public void deploymentDescriptorTest() throws Exception {
    JaxbDeploymentDescriptor depDescriptor = new JaxbDeploymentDescriptor();

    depDescriptor.setAuditMode(AuditMode.JMS);
    depDescriptor.setAuditPersistenceUnit("myDatabasePersistenceUnit");
    String[] classes = {"org.test.First", "org.more.test.Second"};
    depDescriptor.setClasses(Arrays.asList(classes));

    depDescriptor.setConfiguration(getNamedObjectModeList("conf"));
    depDescriptor.setEnvironmentEntries(getNamedObjectModeList("envEnt"));
  }

  private List<NamedObjectModel> getNamedObjectModeList(String type) {
    type = "-" + type;
    List<NamedObjectModel> namedObjectModelList = new ArrayList<NamedObjectModel>();
    for (int i = 0; i < 2; ++i) {
      NamedObjectModel nom = new NamedObjectModel();
      nom.setIdentifier("id-" + i + type);
      nom.setName("name-" + i + type);
      String[] params = {UUID.randomUUID().toString(), UUID.randomUUID().toString()};
      List<Object> paramList = new ArrayList<Object>();
      paramList.addAll(Arrays.asList(params));
      nom.setParameters(paramList);
      nom.setResolver(i + "-resolver" + type);
      namedObjectModelList.add(nom);
    }
    return namedObjectModelList;
  }

  @Test
  public void funnyCharactersTest() throws Exception {
    String testStr = "test &<>\"\' test";
    JaxbString jaxbStr = new JaxbString(testStr);

    JaxbString copy = testRoundTrip(jaxbStr);
    assertEquals("Funny characters not correctly encoded", testStr, copy.getValue());
  }

  @Test
  public void correlationKeyTest() throws Exception {
    Assume.assumeFalse(getType().equals(TestType.YAML));

    JaxbCorrelationKey corrKey = new JaxbCorrelationKey();
    corrKey.setName("anton");
    List<JaxbCorrelationProperty> properties = new ArrayList<JaxbCorrelationProperty>(3);
    corrKey.setJaxbProperties(properties);
    properties.add(new JaxbCorrelationProperty("name", "value"));
    properties.add(new JaxbCorrelationProperty("only-a-value"));
    properties.add(new JaxbCorrelationProperty("ngalan", "bili"));

    JaxbCorrelationKey copyCorrKey = testRoundTrip(corrKey);

    assertEquals("name", corrKey.getName(), copyCorrKey.getName());
    assertEquals(
        "prop list size", corrKey.getProperties().size(), copyCorrKey.getProperties().size());
    List<CorrelationProperty<?>> propList = corrKey.getProperties();
    List<CorrelationProperty<?>> copyPropList = copyCorrKey.getProperties();
    for (int i = 0; i < propList.size(); ++i) {
      CorrelationProperty<?> prop = propList.get(i);
      CorrelationProperty<?> copyProp = copyPropList.get(i);
      assertEquals(i + ": name", prop.getName(), copyProp.getName());
      assertEquals(i + ": type", prop.getType(), copyProp.getType());
      assertEquals(i + ": value", prop.getValue(), copyProp.getValue());
    }
  }

  @Test
  public void wrapperTypesTest() throws Exception {

    Object[] inputs = {
      true,
      new Byte("1").byteValue(),
      new Character('a').charValue(),
      new Double(23.01).doubleValue(),
      new Float(46.02).floatValue(),
      1011,
      1012,
      new Short("10").shortValue(),
      "string",
    };

    for (Object input : inputs) {
      logger.debug("Testing round trip serialization in wrapper for " + input.getClass().getName());
      Object copyInput = wrapperRoundTrip(input);
      assertEquals(
          input.getClass().getSimpleName() + " wrapped round trip failed!", input, copyInput);
    }

    Integer[] integerArr = {1039, 3858, 239502};
    int[] intArr = {1039, 3858, 239502};
    double[] doubleArr = {2.01, 3.02, 4.03};
    String[] stringArr = {"all", "about", "that", "base"};

    // check that constructor works
    new JaxbArray(doubleArr);

    Object[] arrInputs = {intArr, integerArr, doubleArr, stringArr};

    for (Object input : arrInputs) {
      logger.debug("Testing round trip serialization in wrapper for " + input.getClass().getName());
      int length = Array.getLength(input);
      Object copyInput = wrapperRoundTrip(input);
      assertNotNull("Null copy for " + input.getClass().getName(), copyInput);
      assertEquals("Array length", Array.getLength(input), Array.getLength(copyInput));
      for (int i = 0; i < length; ++i) {
        assertEquals(
            "Element " + i + " inequal in " + input.getClass().getSimpleName() + " instance",
            Array.get(input, i),
            Array.get(copyInput, i));
      }
    }

    {
      List<String> list = new ArrayList<String>();
      list.add("one");
      List<String> copyList = wrapperRoundTrip(list);
      assertEquals(
          list.getClass().getSimpleName() + "round trip failed!",
          list.iterator().next(),
          copyList.iterator().next());
    }

    {
      Set<String> set = new HashSet<String>();
      set.add("one");
      Set<String> copySet = wrapperRoundTrip(set);
      assertEquals(
          set.getClass().getSimpleName() + "round trip failed!",
          set.iterator().next(),
          copySet.iterator().next());
    }

    {
      Map<String, Object> map = new HashMap<String, Object>(1);
      map.put("one", "two");
      Map<String, Object> copyMap = wrapperRoundTrip(map);
      assertEquals(
          copyMap.getClass().getSimpleName() + " round trip failed!",
          map.get("one"),
          copyMap.get("one"));
    }
  }

  @SuppressWarnings("unchecked")
  private <T> T wrapperRoundTrip(T value) throws Exception {
    JaxbType<T> wrapper = null;
    if (value instanceof Boolean) {
      wrapper = (JaxbType<T>) new JaxbBoolean((Boolean) value);
    } else if (value instanceof Byte) {
      wrapper = (JaxbType<T>) new JaxbByte((Byte) value);
    } else if (value instanceof Character) {
      wrapper = (JaxbType<T>) new JaxbCharacter((Character) value);
    } else if (value instanceof Double) {
      wrapper = (JaxbType<T>) new JaxbDouble((Double) value);
    } else if (value instanceof Float) {
      wrapper = (JaxbType<T>) new JaxbFloat((Float) value);
    } else if (value instanceof Integer) {
      wrapper = (JaxbType<T>) new JaxbInteger((Integer) value);
    } else if (value instanceof Long) {
      wrapper = (JaxbType<T>) new JaxbLong((Long) value);
    } else if (value instanceof Short) {
      wrapper = (JaxbType<T>) new JaxbShort((Short) value);
    } else if (value instanceof String) {
      wrapper = (JaxbType<T>) new JaxbString((String) value);
    } else if (value.getClass().isArray()) {
      wrapper = (JaxbType<T>) new JaxbArray(value);
    } else if (value instanceof List) {
      wrapper = (JaxbType<T>) new JaxbList((List) value);
    } else if (value instanceof Set) {
      wrapper = (JaxbType<T>) new JaxbSet((Set) value);
    } else if (value instanceof Map) {
      wrapper = (JaxbType<T>) new JaxbMap((Map) value);
    } else {
      fail(
          "Modify the "
              + Thread.currentThread().getStackTrace()[1].getMethodName()
              + " to also round trip "
              + value.getClass().getSimpleName()
              + " instances!");
    }
    return testRoundTrip(wrapper).getValue();
  }
}
/** @author Nils Olsson */
public final class TestExecutor implements Executor {

  private static final Reflections reflections =
      new Reflections(
          new ConfigurationBuilder()
              .addUrls(filter(ClasspathHelper.forJavaClassPath(), ClasspathHelper.forClassLoader()))
              .addScanners(new SubTypesScanner(), new TypeAnnotationsScanner()));

  private static Collection<URL> filter(Collection<URL> classPath, Collection<URL> classLoader) {
    Reflections.log = null;
    List<URL> urls = new ArrayList<>(), filteredUrls = new ArrayList<>();
    urls.addAll(classPath);
    urls.addAll(classLoader);
    for (URL url : urls) {
      if (!filteredUrls.contains(url) && new File(url.getFile()).exists()) {
        filteredUrls.add(url);
      }
    }
    return filteredUrls;
  }

  private final Configuration configuration;
  private final MachineConfiguration machineConfiguration;
  private final Map<Context, MachineException> failures = new HashMap<>();
  private final Machine machine;
  private Result result;

  public TestExecutor(Configuration configuration) {
    this.configuration = configuration;
    this.machineConfiguration = createMachineConfiguration(AnnotationUtils.findTests(reflections));
    this.machine = createMachine(machineConfiguration);
  }

  public TestExecutor(Class<?>... tests) {
    this.configuration = new Configuration();
    this.machineConfiguration = createMachineConfiguration(Arrays.asList(tests));
    this.machine = createMachine(machineConfiguration);
  }

  public TestExecutor(Context... contexts) {
    this.configuration = new Configuration();
    this.machineConfiguration = new MachineConfiguration();
    this.machine = new SimpleMachine(contexts);
  }

  public TestExecutor(Collection<Context> contexts) {
    this.configuration = new Configuration();
    this.machineConfiguration = new MachineConfiguration();
    this.machine = new SimpleMachine(contexts);
  }

  @Override
  public Machine getMachine() {
    return machine;
  }

  private MachineConfiguration createMachineConfiguration(Collection<Class<?>> testClasses) {
    MachineConfiguration machineConfiguration = new MachineConfiguration();
    for (Class<?> testClass : testClasses) {
      GraphWalker annotation = testClass.getAnnotation(GraphWalker.class);
      if (isTestIncluded(annotation, testClass.getName())) {
        ContextConfiguration contextConfiguration = new ContextConfiguration();
        contextConfiguration.setTestClass(testClass);
        machineConfiguration.addContextConfiguration(contextConfiguration);
      }
    }
    return machineConfiguration;
  }

  private Collection<Context> createContexts(MachineConfiguration machineConfiguration) {
    Set<Context> contexts = new HashSet<>();
    for (ContextConfiguration contextConfiguration :
        machineConfiguration.getContextConfigurations()) {
      Context context = createContext(contextConfiguration.getTestClass());
      configureContext(context);
      contexts.add(context);
    }
    return contexts;
  }

  private Context createContext(Class<?> testClass) {
    try {
      return (Context) testClass.newInstance();
    } catch (Throwable e) {
      throw new TestExecutionException("Failed to create context");
    }
  }

  private void configureContext(Context context) {
    Set<Model> models = AnnotationUtils.getAnnotations(context.getClass(), Model.class);
    GraphWalker annotation = context.getClass().getAnnotation(GraphWalker.class);
    if (!models.isEmpty()) {
      Path path = Paths.get(models.iterator().next().file());
      ContextFactoryScanner.get(reflections, path).create(path, context);
    }
    if (!"".equals(annotation.value())) {
      context.setPathGenerator(GeneratorFactory.parse(annotation.value()));
    } else {
      context.setPathGenerator(PathGeneratorFactory.createPathGenerator(annotation));
    }
    if (!"".equals(annotation.start())) {
      context.setNextElement(getElement(context.getModel(), annotation.start()));
    }
  }

  private Machine createMachine(MachineConfiguration machineConfiguration) {
    Collection<Context> contexts = createContexts(machineConfiguration);
    Machine machine = new SimpleMachine(contexts);
    for (Context context : machine.getContexts()) {
      if (context instanceof Observer) {
        machine.addObserver((Observer) context);
      }
    }
    return machine;
  }

  @Override
  public MachineConfiguration getMachineConfiguration() {
    return machineConfiguration;
  }

  @Override
  public Result execute() {
    return execute(false);
  }

  @Override
  public Result execute(boolean ignoreErrors) {
    result = new Result(machine.getContexts().size());
    executeAnnotation(BeforeExecution.class, machine);
    try {
      Context context = null;
      while (machine.hasNextStep()) {
        if (null != context) {
          executeAnnotation(BeforeElement.class, context);
        }
        context = machine.getNextStep();
        executeAnnotation(AfterElement.class, context);
      }
    } catch (MachineException e) {
      failures.put(e.getContext(), e);
    }
    executeAnnotation(AfterExecution.class, machine);
    updateResult(result, machine);
    if (!ignoreErrors && !failures.isEmpty()) {
      throw new TestExecutionException("Test execution contains failures");
    }
    return result;
  }

  @Override
  public Result getResult() {
    return result;
  }

  private void updateResult(Result result, Machine machine) {
    int completed = 0, failed = 0, notExecuted = 0, incomplete = 0;
    for (Context context : machine.getContexts()) {
      switch (context.getExecutionStatus()) {
        case COMPLETED:
          {
            completed++;
          }
          break;
        case FAILED:
          {
            failed++;
          }
          break;
        case NOT_EXECUTED:
          {
            notExecuted++;
          }
          break;
        case EXECUTING:
          {
            incomplete++;
          }
      }
    }
    result.setCompletedCount(completed);
    result.setFailedCount(failed);
    result.setNotExecutedCount(notExecuted);
    result.setIncompleteCount(incomplete);
    for (MachineException exception : getFailures()) {
      result.addError(getStackTrace(exception.getCause()));
    }
  }

  private String getStackTrace(Throwable throwable) {
    StringWriter writer = new StringWriter();
    throwable.printStackTrace(new PrintWriter(writer, true));
    return writer.getBuffer().toString();
  }

  private boolean isTestIncluded(GraphWalker annotation, String name) {
    boolean belongsToGroup = false;
    for (String group : annotation.groups()) {
      for (String definedGroups : configuration.getGroups()) {
        if (SelectorUtils.match(definedGroups, group)) {
          belongsToGroup = true;
          break;
        }
      }
    }
    if (belongsToGroup) {
      for (String exclude : configuration.getExcludes()) {
        if (SelectorUtils.match(exclude, name)) {
          return false;
        }
      }
      for (String include : configuration.getIncludes()) {
        if (SelectorUtils.match(include, name)) {
          return true;
        }
      }
    }
    return false;
  }

  private Element getElement(RuntimeModel model, String name) {
    List<Element> elements = model.findElements(name);
    if (null == elements || 0 == elements.size()) {
      throw new TestExecutionException("Start element not found");
    }
    if (1 < elements.size()) {
      throw new TestExecutionException("Ambiguous start element defined");
    }
    return elements.get(0);
  }

  private void executeAnnotation(Class<? extends Annotation> annotation, Machine machine) {
    for (Context context : machine.getContexts()) {
      executeAnnotation(annotation, context);
    }
  }

  private void executeAnnotation(Class<? extends Annotation> annotation, Context context) {
    AnnotationUtils.execute(annotation, context);
  }

  @Override
  public boolean isFailure(Context context) {
    return failures.containsKey(context);
  }

  @Override
  public MachineException getFailure(Context context) {
    return failures.get(context);
  }

  @Override
  public Collection<MachineException> getFailures() {
    return failures.values();
  }

  public void reportResults(File file, Date startTime, Properties properties) {
    new XMLReportGenerator(startTime, properties).writeReport(file, this);
    if (0 < getFailures().size()) {
      throw new TestExecutionException(
          MessageFormat.format(
              "There are test failures.\n\n Please refer to {0} for the individual test results.",
              file.getAbsolutePath()));
    }
  }
}
Beispiel #14
0
  @Override
  public void beforeStart(final Application application) {
    final Reflections reflections =
        new Reflections(
            new ConfigurationBuilder()
                .filterInputsBy(new FilterBuilder.Exclude(FilterBuilder.prefix("com.google")))
                .addUrls(ClasspathHelper.forClassLoader(application.classloader()))
                .addScanners(new SubTypesScanner()));

    // automatic Guice module detection
    Set<Class<? extends AbstractModule>> guiceModules =
        reflections.getSubTypesOf(AbstractModule.class);
    for (Class<? extends Module> moduleClass : guiceModules) {
      try {
        if (!moduleClass.isAnonymousClass()) {
          modules.add(moduleClass.newInstance());
        }
      } catch (InstantiationException e) {
        throw Throwables.propagate(e);
      } catch (IllegalAccessException e) {
        throw Throwables.propagate(e);
      }
    }

    modules.add(
        new AbstractModule() {
          @Override
          protected void configure() {
            bind(Application.class).toInstance(application);
            bind(Reflections.class).toInstance(reflections);

            Names.bindProperties(
                this.binder(),
                fromKeys(
                    application.configuration().keys(),
                    new Function<String, String>() {
                      @Override
                      public String apply(String key) {
                        // remove after https://play.lighthouseapp.com/projects/82401/tickets/372 is
                        // fixed
                        if (key.contains("akka")) return null;

                        return application.configuration().getString(key);
                      }
                    }));

            for (Class<? extends Controller> controllerClass :
                reflections.getSubTypesOf(Controller.class)) {
              requestStaticInjection(controllerClass);
            }

            // bind all services
            Multibinder<Service> serviceBinder = Multibinder.newSetBinder(binder(), Service.class);
            for (Class<? extends Service> serviceImplClass :
                reflections.getSubTypesOf(AbstractService.class)) {
              serviceBinder.addBinding().to(serviceImplClass).asEagerSingleton();
            }
            for (Class<? extends Service> serviceImplClass :
                reflections.getSubTypesOf(AbstractIdleService.class)) {
              serviceBinder.addBinding().to(serviceImplClass).asEagerSingleton();
            }
            for (Class<? extends Service> serviceImplClass :
                reflections.getSubTypesOf(AbstractExecutionThreadService.class)) {
              serviceBinder.addBinding().to(serviceImplClass).asEagerSingleton();
            }

            // bind actor - todo use reflections for this

            // start/stop services after injection and on shutdown of the Play app
            bindListener(
                MoreMatchers.subclassesOf(Service.class),
                new TypeListener() {
                  @Override
                  public <I> void hear(TypeLiteral<I> typeLiteral, TypeEncounter<I> typeEncounter) {
                    typeEncounter.register(
                        new InjectionListener<I>() {
                          @Override
                          public void afterInjection(final I i) {
                            onStartListeners.add(
                                new OnStartListener() {
                                  @Override
                                  public void onApplicationStart(
                                      Application application, Injector injector) {
                                    Logger.info(String.format("Starting %s", i.toString()));
                                    ((Service) i).start();

                                    onStopListeners.add(
                                        new OnStopListener() {
                                          @Override
                                          public void onApplicationStop(Application application) {
                                            Logger.info(String.format("Stopping %s", i.toString()));
                                            ((Service) i).stop();
                                          }
                                        });
                                  }
                                });
                          }
                        });
                  }
                });
          }
        });
  }