diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-05-10 16:02:45 -0400 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2016-05-10 16:02:45 -0400 |
| commit | 61fd71f69e080790da722e0e03b71ecd7c2538a2 (patch) | |
| tree | e5c1150b27b84d550f807e44ac82688216451f00 /BJC-Utils2/src/main/java/bjc/utils/components | |
| parent | 87ae1dfc8d8cb7b51d7bda4750ce841bbe691cfc (diff) | |
General update
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/components')
5 files changed, 108 insertions, 115 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java index 9429dde..ab48c9b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescription.java @@ -10,19 +10,19 @@ public class ComponentDescription implements IDescribedComponent { private static void sanityCheckArgs(String name, String author, String description, int version) { if (name == null) { - throw new IllegalArgumentException( - "Component name can't be null"); + throw new NullPointerException("Component name can't be null"); } else if (author == null) { - throw new IllegalArgumentException( + throw new NullPointerException( "Component author can't be null"); } else if (description == null) { - throw new IllegalArgumentException( + throw new NullPointerException( "Component description can't be null"); - } else if (version < 0) { + } else if (version <= 0) { throw new IllegalArgumentException( "Component version must be greater than 0"); } } + /** * The author of the component */ @@ -53,8 +53,7 @@ public class ComponentDescription implements IDescribedComponent { * @param version * The version of the component * @throws IllegalArgumentException - * thrown if name, author or description is null, or if - * version is less than 1 + * thrown if version is less than 1 */ public ComponentDescription(String name, String author, String description, int version) { diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java index be0a65b..b35c77b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionFileParser.java @@ -1,13 +1,11 @@ package bjc.utils.components; import java.io.InputStream; -import java.util.function.BiConsumer; -import bjc.utils.exceptions.PragmaFormatException; -import bjc.utils.funcdata.FunctionalStringTokenizer; -import bjc.utils.funcutils.ListUtils; import bjc.utils.parserutils.RuleBasedConfigReader; +import static bjc.utils.parserutils.RuleBasedReaderPragmas.*; + /** * Read a component description from a file * @@ -15,8 +13,10 @@ import bjc.utils.parserutils.RuleBasedConfigReader; * */ public class ComponentDescriptionFileParser { + // The reader used to read in component descriptions private static RuleBasedConfigReader<ComponentDescriptionState> reader; + // Initialize the reader and its pragmas static { // This reader works entirely off of pragmas, so no need to handle // rules @@ -31,19 +31,6 @@ public class ComponentDescriptionFileParser { setupReaderPragmas(); } - private static BiConsumer<FunctionalStringTokenizer, ComponentDescriptionState> buildStringCollapserPragma( - String pragmaName) { - return (tokenizer, state) -> { - if (!tokenizer.hasMoreTokens()) { - throw new PragmaFormatException("Pragma " + pragmaName - + " requires one string argument"); - } - - state.setName(ListUtils - .collapseTokens(tokenizer.toList((strang) -> strang))); - }; - } - /** * Parse a component description from a stream * @@ -51,42 +38,29 @@ public class ComponentDescriptionFileParser { * The stream to parse from * @return The description parsed from the stream */ - public static ComponentDescription fromStream( - InputStream inputSource) { + public static ComponentDescription + fromStream(InputStream inputSource) { ComponentDescriptionState readState = reader .fromStream(inputSource, new ComponentDescriptionState()); return readState.toDescription(); } + /* + * Create all the pragmas the reader needs to function + */ private static void setupReaderPragmas() { - reader.addPragma("name", buildStringCollapserPragma("name")); + reader.addPragma("name", buildStringCollapser("name", + (name, state) -> state.setName(name))); - reader.addPragma("author", buildStringCollapserPragma("author")); + reader.addPragma("author", buildStringCollapser("author", + (author, state) -> state.setAuthor(author))); reader.addPragma("description", - buildStringCollapserPragma("description")); + buildStringCollapser("description", (description, + state) -> state.setDescription(description))); - reader.addPragma("version", (tokenizer, state) -> { - if (!tokenizer.hasMoreTokens()) { - throw new PragmaFormatException( - "Pragma version requires one integer argument"); - } - - String token = tokenizer.nextToken(); - - try { - state.setVersion(Integer.parseInt(token)); - } catch (NumberFormatException nfex) { - PragmaFormatException pfex = new PragmaFormatException( - "Argument " + token - + " to version pragma isn't a valid integer. " - + "This pragma requires a integer argument"); - - pfex.initCause(nfex); - - throw pfex; - } - }); + reader.addPragma("version", buildInteger("version", + (version, state) -> state.setVersion(version))); } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java index 199009c..a17a70b 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/ComponentDescriptionState.java @@ -7,12 +7,16 @@ package bjc.utils.components; * */ public class ComponentDescriptionState { + // Tentative name of this component private String name; + // Tentative description of this componet private String description; + // Tentative author of this component private String author; + // Tentative version of this component private int version; /** diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java index e05afc0..182549c 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/FileComponentRepository.java @@ -6,42 +6,36 @@ import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; import java.util.function.BiPredicate; import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; import bjc.utils.data.IHolder; import bjc.utils.data.Identity; -import bjc.utils.funcdata.FunctionalList; import bjc.utils.funcdata.FunctionalMap; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; import bjc.utils.funcutils.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - /** * A component repository that loads its components from files in a * directory * * @author ben * - * @param <E> + * @param <ComponentType> * The type of component being read in */ -public class FileComponentRepository<E extends IDescribedComponent> - implements IComponentRepository<E> { +public class FileComponentRepository<ComponentType extends IDescribedComponent> + implements IComponentRepository<ComponentType> { + // The logger to use for storing data about this class + private static final Logger CLASS_LOGGER = + Logger.getLogger("FileComponentRepository"); - private static final Logger CLASS_LOGGER = LoggerFactory - .getLogger(FileComponentRepository.class); + // The internal storage of components + private IMap<String, ComponentType> components; - /** - * The internal storage of components - */ - private IFunctionalMap<String, E> components; - - /** - * The path that all the components came from - */ - private Path sourceDirectory; + // The path that all the components came from + private Path sourceDirectory; /** * Create a new component repository sourcing components from files in @@ -57,33 +51,47 @@ public class FileComponentRepository<E extends IDescribedComponent> * The function to use to convert files to components */ public FileComponentRepository(File directory, - Function<File, ? extends E> componentReader) { + Function<File, ? extends ComponentType> componentReader) { + // Make sure we have valid arguments if (!directory.isDirectory()) { throw new IllegalArgumentException("File " + directory + " is not a directory.\n" + "Components can only be read from a directory"); + } else if (componentReader == null) { + throw new NullPointerException( + "Component reader must not be null"); } + // Initialize our fields components = new FunctionalMap<>(); - sourceDirectory = directory.toPath().toAbsolutePath(); + // Marker for making sure we don't skip the parent IHolder<Boolean> isFirstDir = new Identity<>(true); - BiPredicate<Path, BasicFileAttributes> firstLevelTraverser = (pth, - attr) -> { - if (attr.isDirectory() && !isFirstDir.getValue()) { - // Don't skip the first directory, that's the - // parent - isFirstDir.replace(false); - // Skip directories, they probably have - // component - return false; - } - - return true; - }; - + // Predicate to use to traverse all the files in a directory, but + // not recurse into sub-directories + BiPredicate<Path, BasicFileAttributes> firstLevelTraverser = + (pth, attr) -> { + if (attr.isDirectory() && !isFirstDir.getValue()) { + + /* + * Skip directories, they probably have component + * support files. + */ + return false; + } + + /* + * Don't skip the first directory, that's the parent + * directory + */ + isFirstDir.replace(false); + + return true; + }; + + // Try reading components try { FileUtils.traverseDirectory(sourceDirectory, firstLevelTraverser, (pth, attr) -> { @@ -93,28 +101,23 @@ public class FileComponentRepository<E extends IDescribedComponent> return true; }); } catch (IOException ioex) { - CLASS_LOGGER.warn("Error found reading component from file.", - ioex); + CLASS_LOGGER.log(Level.WARNING, ioex, + () -> "Error found reading component from file."); } } @Override - public E getComponentByName(String name) { + public ComponentType getByName(String name) { return components.get(name); } @Override - public IFunctionalList<E> getComponentList() { - IFunctionalList<E> returnedList = new FunctionalList<>(); - - components - .forEach((name, component) -> returnedList.add(component)); - - return returnedList; + public IList<ComponentType> getList() { + return components.valueList(); } @Override - public IFunctionalMap<String, E> getComponents() { + public IMap<String, ComponentType> getAll() { return components; } @@ -123,26 +126,38 @@ public class FileComponentRepository<E extends IDescribedComponent> return "Components read from directory " + sourceDirectory + "."; } - private void loadComponent(Function<File, ? extends E> componentReader, + /* + * Load a component from a file + */ + private void loadComponent( + Function<File, ? extends ComponentType> componentReader, Path pth) { try { - E component = componentReader.apply(pth.toFile()); + // Try to load the component + ComponentType component = componentReader.apply(pth.toFile()); if (component == null) { throw new NullPointerException( "Component reader read null component"); } else if (!components.containsKey(component.getName())) { - components.put(component.getName(), component); + // We only care about the latest version of a component + ComponentType oldComponent = + components.put(component.getName(), component); + + if (oldComponent.getVersion() > component.getVersion()) { + components.put(oldComponent.getName(), oldComponent); + } } else { - CLASS_LOGGER.warn("Found a duplicate component.\n" + CLASS_LOGGER.warning("Found a duplicate component.\n" + "Multiple versions of the same component are not currently supported.\n" - + "The component" + component - + " will not be registered ."); + + "Only the latest version of the component" + + component + " will be registered ."); } } catch (Exception ex) { - CLASS_LOGGER.warn("Error found reading component from file " - + pth.toString() - + ". This component will not be loaded", ex); + CLASS_LOGGER.log(Level.WARNING, ex, + () -> "Error found reading component from file " + + pth.toString() + + ". This component will not be loaded"); } } }
\ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java b/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java index 6780f2e..2644276 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java +++ b/BJC-Utils2/src/main/java/bjc/utils/components/IComponentRepository.java @@ -1,17 +1,18 @@ package bjc.utils.components; -import bjc.utils.funcdata.IFunctionalList; -import bjc.utils.funcdata.IFunctionalMap; +import bjc.utils.funcdata.IList; +import bjc.utils.funcdata.IMap; /** - * A collection of implementations of {@link IDescribedComponent} + * A collection of implementations of a particular type of + * {@link IDescribedComponent} * * @author ben * - * @param <E> + * @param <ComponentType> * The type of components contained in this repository */ -public interface IComponentRepository<E extends IDescribedComponent> { +public interface IComponentRepository<ComponentType extends IDescribedComponent> { /** * Get a component with a specific name * @@ -20,15 +21,15 @@ public interface IComponentRepository<E extends IDescribedComponent> { * @return The named component, or null if no component with that name * exists */ - public E getComponentByName(String name); + public ComponentType getByName(String name); /** * Get a list of all the registered componets * * @return A list of all the registered components */ - public default IFunctionalList<E> getComponentList() { - return getComponents().valueList(); + public default IList<ComponentType> getList() { + return getAll().valueList(); } /** @@ -37,7 +38,7 @@ public interface IComponentRepository<E extends IDescribedComponent> { * @return A map from component name to component, containing all of * the components in the repositories */ - public IFunctionalMap<String, E> getComponents(); + public IMap<String, ComponentType> getAll(); /** * Get the source from which these components came |
