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

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:
 * 
 * #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;
	}
}