// ============================================================================
//
// Copyright (C) 2006-2016 Talend Inc. - www.talend.com
//
// This source code is available under agreement available at
// %InstallDIR%\features\org.talend.rcp.branding.%PRODUCTNAME%\%PRODUCTNAME%license.txt
//
// You should have received a copy of the agreement
// along with this program; if not, write to Talend SA
// 9 rue Pages 92150 Suresnes, France
//
// ============================================================================
package org.talend.dataquality.common.inference;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.NotImplementedException;
import org.apache.log4j.Logger;
/**
* Provides a way to combine several {@link Analyzer} together and a
* {@link org.talend.datascience.common.inference.Analyzers.Result result} that stores all underlying results.
*
* @see #with(Analyzer[])
*/
public class Analyzers implements Analyzer<Analyzers.Result> {
private static final long serialVersionUID = 3718737129904789140L;
private static final Logger LOGGER = Logger.getLogger(Analyzers.class);
private final Analyzer<?>[] analyzerArrays;
private final ResizableList<Result> results = new ResizableList<>(Result.class);
private Analyzers(Analyzer<?>... analyzers) {
this.analyzerArrays = analyzers;
}
/**
* Creates a single analyzer with provided {@link Analyzer analyzers}.
*
* @param analyzers The analyzers to be combined together.
* @return A single analyzer that ensure all underlying analyzers get called.
*/
public static Analyzer<Analyzers.Result> with(Analyzer<?>... analyzers) {
return new Analyzers(analyzers);
}
@Override
public void init() {
for (Analyzer<?> analyzer : analyzerArrays) {
analyzer.init();
}
}
@Override
public boolean analyze(String... record) {
boolean result = true;
results.resize(record.length);
for (Analyzer<?> analyzer : analyzerArrays) {
result &= analyzer.analyze(record);
}
return result;
}
@Override
public void end() {
for (Analyzer<?> executor : analyzerArrays) {
executor.end();
}
}
@Override
public List<Result> getResult() {
for (Analyzer<?> analyzer : analyzerArrays) {
final List<?> analysis = analyzer.getResult();
if (analysis != null) {
for (int j = 0; j < analysis.size(); j++) {
results.get(j).add(analysis.get(j));
}
}
}
return results;
}
/**
* A generic composite result which aggregates several analyzer's results.
*/
public static class Result {
private final Map<Class<?>, Object> results = new HashMap<>();
public <T> T get(Class<T> clazz) {
if (results.containsKey(clazz)) {
return clazz.cast(results.get(clazz));
}
throw new IllegalArgumentException("No result of type '" + clazz.getName() + "'.");
}
public <T> boolean exist(Class<T> clazz) {
return results.containsKey(clazz);
}
public void add(Object result) {
results.put(result.getClass(), result);
}
}
@Override
public Analyzer<Result> merge(Analyzer<Result> another) {
throw new NotImplementedException();
}
@Override
public void close() throws Exception {
for (Analyzer<?> analyzer : analyzerArrays) {
try {
analyzer.close();
} catch (Exception e) {
LOGGER.error("Unable to close " + analyzer, e);
}
}
}
}