summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java
blob: 4b8d87b9f6a6e888f7385d5ba39115b0174f15c7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package bjc.utils.components;

import java.io.File;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import bjc.utils.funcdata.FunctionalList;

/**
 * A component repository that loads its components from files in a
 * directory
 * 
 * @author ben
 *
 * @param <E>
 *            The type of component being read in
 */
public class FileComponentRepository<E extends IDescribedComponent>
		implements IComponentRepository<E> {

	private static final Logger	CLASS_LOGGER	=
			LoggerFactory.getLogger(FileComponentRepository.class);

	/**
	 * The internal storage of components
	 */
	private Map<String, E>		components;

	/**
	 * The path that all the components came from
	 */
	private Path				sourceDirectory;

	/**
	 * Create a new component repository sourcing components from files in
	 * a directory
	 * 
	 * An exception thrown during the loading of a component will only
	 * cause the loading of that component to fail, but a warning will be
	 * logged.
	 * 
	 * @param directory
	 *            The directory to read component files from
	 * @param componentReader
	 *            The function to use to convert files to components
	 */
	public FileComponentRepository(File directory,
			Function<File, E> componentReader) {
		if (!directory.isDirectory()) {
			throw new IllegalArgumentException("File " + directory
					+ " is not a directory.\n"
					+ "Components can only be read from a directory");
		}

		components = new HashMap<>();
		sourceDirectory = directory.toPath().toAbsolutePath();

		File[] listFiles = directory.listFiles();

		if (listFiles == null) {
			throw new IllegalArgumentException("File " + directory
					+ " is not a valid directory.\n"
					+ "Components can only be read from a directory");
		}

		for (File componentFile : listFiles) {
			if (componentFile.isDirectory()) {
				// Do nothing with directories. They probably contain
				// support files for components
			} else {
				try {
					E component = componentReader.apply(componentFile);

					if (component == null) {
						throw new NullPointerException(
								"Component reader read null component");
					} else if (!components
							.containsKey(component.getName())) {
						components.put(component.getName(), component);
					} else {
						CLASS_LOGGER.warn("Found a duplicate component.\n"
								+ "Multiple versions of the same component are not currently supported.\n"
								+ "The component" + component
								+ " will not be registered .");
					}
				} catch (Exception ex) {
					CLASS_LOGGER
							.warn("Error found reading component from file "
									+ componentFile.toString()
									+ ". This component will not be loaded");
				}

			}
		}
	}

	@Override
	public FunctionalList<E> getComponentList() {
		FunctionalList<E> returnedList = new FunctionalList<>();

		components
				.forEach((name, component) -> returnedList.add(component));

		return returnedList;
	}

	@Override
	public Map<String, E> getComponents() {
		return components;
	}

	@Override
	public String getSource() {
		return "Components read from directory " + sourceDirectory + ".";
	}

	@Override
	public E getComponentByName(String name) {
		return components.get(name);
	}
}