io.earcam.utilitarian.site.search.offline.ConfigurationModel Maven / Gradle / Ivy
/*-
* #%L
* io.earcam.utilitarian.site.search.offline
* %%
* Copyright (C) 2017 earcam
* %%
* SPDX-License-Identifier: (BSD-3-Clause OR EPL-1.0 OR Apache-2.0 OR MIT)
*
* You must choose to accept, in full - any individual or combination of
* the following licenses:
*
* - BSD-3-Clause
* - EPL-1.0
* - Apache-2.0
* - MIT
*
* #L%
*/
package io.earcam.utilitarian.site.search.offline;
import static io.earcam.utilitarian.site.search.offline.Crawler.crawler;
import static java.util.stream.Collectors.toMap;
import static java.util.stream.Collectors.toSet;
import static java.util.stream.StreamSupport.stream;
import java.io.File;
import java.net.URI;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Stream;
public abstract class ConfigurationModel {
public static class Step extends ConfigurationModel {}
public static class Mapping {
private File dir;
private URI uri;
public File getDir()
{
return dir;
}
static Path dirAsPath(Mapping mapping)
{
return mapping.getDir().toPath();
}
public void setDir(File dir)
{
this.dir = dir;
}
public URI getUri()
{
return uri;
}
public void setUri(URI uri)
{
this.uri = uri;
}
}
public static class Indexing extends ConfigurationModel {
public Indexer build()
{
return create(Indexer.class, this);
}
}
static T create(Class type, ConfigurationModel model)
{
T component = serviceById(type, model.getId());
component.configure(model.getConfiguration());
return component;
}
private static S serviceById(Class service, String id)
{
return serviceStream(service)
.filter(s -> id.equals(s.id()))
.findFirst()
.orElseThrow(() -> new IllegalStateException("Not SPI service with id '" + id
+ "' found of type '" + service.getCanonicalName() + "'"));
}
private static Stream serviceStream(Class service)
{
return stream(ServiceLoader.load(service).spliterator(), false);
}
public static class Crawling {
private List mappings;
private List steps;
public List getMappings()
{
return mappings;
}
public void setMappings(List mappings)
{
this.mappings = mappings;
}
public List getSteps()
{
return steps;
}
public void setSteps(List steps)
{
this.steps = steps;
}
public Crawler build()
{
Crawler crawler = crawler(mappings.stream()
.collect(toMap(Mapping::dirAsPath, Mapping::getUri)));
Set filters = serviceIds(Filter.class);
Set processors = serviceIds(Processor.class);
for(Step step : steps) {
if(filters.contains(step.getId())) {
crawler.filter(create(Filter.class, step));
} else if(processors.contains(step.getId())) {
crawler.processor(create(Processor.class, step));
} else {
throw new IllegalStateException("No filter or processor found via SPI with ID '" + step.getId() + "'");
}
}
return crawler;
}
private static Set serviceIds(Class service)
{
return serviceStream(service)
.map(Component::id)
.collect(toSet());
}
}
private String id;
private Map configuration;
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public Map getConfiguration()
{
return configuration;
}
public void setConfiguration(Map configuration)
{
this.configuration = configuration;
}
}