/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* 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 com.asakusafw.testdriver;
import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.asakusafw.testdriver.compiler.ArtifactMirror;
import com.asakusafw.testdriver.compiler.BatchMirror;
import com.asakusafw.testdriver.compiler.CompilerConfiguration;
import com.asakusafw.testdriver.compiler.CompilerToolkit;
import com.asakusafw.testdriver.compiler.GraphElement;
import com.asakusafw.testdriver.compiler.JobflowMirror;
import com.asakusafw.testdriver.compiler.util.DeploymentUtil;
import com.asakusafw.testdriver.compiler.util.DeploymentUtil.DeployOption;
import com.asakusafw.utils.graph.Graph;
import com.asakusafw.utils.graph.Graphs;
/**
* Utilities for testers.
* @since 0.8.0
* @version 0.9.0
*/
final class Util {
static final Logger LOG = LoggerFactory.getLogger(Util.class);
private static volatile CompilerToolkit force;
public static void setToolkit(CompilerToolkit toolkit) {
force = toolkit;
}
public static CompilerToolkit getToolkit(Class<?> contextClass) {
Objects.requireNonNull(contextClass);
return Optional.ofNullable(force)
.orElseGet(() -> getToolkit(contextClass.getClassLoader()));
}
public static CompilerToolkit getToolkit(ClassLoader classLoader) {
Objects.requireNonNull(classLoader);
List<CompilerToolkit> candidates = new ArrayList<>();
for (CompilerToolkit tk : ServiceLoader.load(CompilerToolkit.class, classLoader)) {
candidates.add(tk);
}
if (candidates.isEmpty()) {
throw new IllegalStateException("there are no available Asakusa DSL compilers");
}
CompilerToolkit result = candidates.get(0);
if (candidates.size() >= 2) {
List<String> conflicts = new ArrayList<>();
for (CompilerToolkit tk : candidates) {
conflicts.add(tk.getName());
}
LOG.warn(MessageFormat.format(
"multiple Asakusa DSL compilers are detected: {0}",
conflicts));
LOG.warn(MessageFormat.format(
"actual compiler binding is: {0}",
result.getName()));
}
return result;
}
public static CompilerConfiguration getConfiguration(CompilerToolkit toolkit, TestDriverContext context) {
CompilerConfiguration configuration = toolkit.newConfiguration();
configuration.withClassLoader(context.getClassLoader());
configuration.withWorkingDirectory(context.getCompilerWorkingDirectory());
configuration.withOptimizeLevel(context.getCompilerOptimizeLevel());
configuration.withDebugLevel(context.getCompilerDebugLevel());
configuration.withOptions(context.getCompilerOptions());
for (Class<?> type : context.getExtensionTypes()) {
putExtension(context, configuration, type);
}
return configuration;
}
private static <T> void putExtension(TestDriverContext context, CompilerConfiguration conf, Class<T> type) {
T extension = context.getExtension(type);
conf.withExtension(type, extension);
}
public static JobflowMirror getJobflow(BatchMirror batch) {
if (batch.getElements().size() != 1) {
throw new IllegalArgumentException();
}
return batch.getElements().iterator().next();
}
public static void prepare(TestDriverContext context, BatchMirror batch, JobflowMirror jobflow) {
context.setCurrentBatchId(batch.getBatchId());
context.setCurrentFlowId(jobflow.getFlowId());
context.setCurrentExecutionId(MessageFormat.format(
"{0}-{1}-{2}", //$NON-NLS-1$
context.getCallerClass().getSimpleName(),
batch.getBatchId(),
jobflow.getFlowId()));
}
public static void deploy(TestDriverContext context, ArtifactMirror artifact) throws IOException {
File root = context.getBatchApplicationsInstallationPath();
File target = new File(root, artifact.getBatch().getBatchId());
if (root.mkdirs() == false && root.isDirectory() == false) {
LOG.warn(MessageFormat.format(
Messages.getString("JobflowExecutor.warnFailedToCreateDirectory"), //$NON-NLS-1$
target.getAbsolutePath()));
}
DeploymentUtil.deploy(artifact.getContents(), target, DeployOption.DELETE_SOURCE);
File dependenciesDest = context.getLibrariesPackageLocation(artifact.getBatch().getBatchId());
if (dependenciesDest.exists()) {
LOG.debug("Cleaning up dependency libraries: {}", dependenciesDest); //$NON-NLS-1$
DeploymentUtil.delete(dependenciesDest);
}
File dependencies = context.getLibrariesPath();
if (dependencies.exists()) {
LOG.debug("Deplogying dependency libraries: {} -> {}", dependencies, dependenciesDest); //$NON-NLS-1$
if (dependenciesDest.mkdirs() == false && dependenciesDest.isDirectory() == false) {
LOG.warn(MessageFormat.format(
Messages.getString("JobflowExecutor.warnFailedToCreateDirectory"), //$NON-NLS-1$
dependenciesDest.getAbsolutePath()));
}
for (File file : list(dependencies)) {
if (file.isFile() == false) {
continue;
}
LOG.debug("Copying a library: {} -> {}", file, dependenciesDest); //$NON-NLS-1$
DeploymentUtil.deployToDirectory(file, dependenciesDest);
}
}
}
public static <E extends GraphElement<E>> List<E> sort(Collection<? extends E> elements) {
Graph<E> graph = Graphs.newInstance();
for (E element : elements) {
graph.addNode(element);
graph.addEdges(element, element.getBlockers());
}
return Graphs.sortPostOrder(graph);
}
private static List<File> list(File file) {
return Optional.ofNullable(file.listFiles())
.map(Arrays::asList)
.orElse(Collections.emptyList());
}
private Util() {
return;
}
}