diff --git a/.github/workflows/release_build.yml b/.github/workflows/release_build.yml index 3a1eded..5eaa42a 100644 --- a/.github/workflows/release_build.yml +++ b/.github/workflows/release_build.yml @@ -59,8 +59,8 @@ jobs: generateReleaseNotes: true skipIfReleaseExists: true - update-gcm-taskit: - if: ${{ !contains(github.event.head_commit.message, 'update-util-to-') }} + update-gcm: + if: ${{ !endsWith(needs.release.outputs.taskit_version, '0') }} needs: release runs-on: ubuntu-latest permissions: @@ -68,25 +68,25 @@ jobs: env: VERSION: ${{ needs.release.outputs.taskit_version }} steps: - - name: Checkout GCM Taskit + - name: Checkout GCM uses: actions/checkout@v4 with: - repository: HHS/ASPR-ms-gcm-taskit + repository: HHS/ASPR-8 token: ${{ secrets.GHA_BOT }} - - name: Update Taskit version + - name: Update Util version run : | echo "$VERSION" - sed -i "0,/.*<\/taskit.version>/s//$VERSION<\/taskit.version>/g" pom.xml + sed -i "0,/.*<\/util.version>/s//$VERSION<\/util.version>/g" pom.xml - - name: Increment GCM Taskit Version + - name: Increment GCM Version run: | current_version=$(mvn help:evaluate -Dexpression=project.version -q -DforceStdout --file pom.xml) - echo GCM Taskit Version: $current_version + echo GCM Version: $current_version parts=( ${current_version//./ } ) bv=$((parts[2] + 1)) new_version="${parts[0]}.${parts[1]}.${bv}" - echo New GCM Taskit Version: $new_version + echo New GCM Version: $new_version sed -i "0,/.*<\/revision>/s//$new_version<\/revision>/g" pom.xml - name: Setup Git @@ -94,16 +94,16 @@ jobs: git config --global user.name "github-actions" git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com" - - name: Make branch in GCM Taskit + - name: Make branch in GCM run: | - git checkout -b update-taskit-to-$VERSION + git checkout -b update-util-to-$VERSION git add pom.xml - git commit -m "Update taskit to $VERSION" - git push --set-upstream origin update-taskit-to-$VERSION + git commit -m "Update util to $VERSION" + git push --set-upstream origin update-util-to-$VERSION - - name: Make PR in GCM Taskit + - name: Make PR in GCM run: | - gh pr create -R HHS/ASPR-ms-gcm-taskit -B main --fill + gh pr create -R HHS/ASPR-8 -B main --fill gh pr merge -m --auto env: GH_TOKEN: ${{ secrets.GHA_BOT }} \ No newline at end of file diff --git a/README.md b/README.md index 16a0b39..15b7baf 100644 --- a/README.md +++ b/README.md @@ -5,16 +5,16 @@ [![GitHub Workflow Status (with event)][build-shield]][build-url] # Translation And Serialization Toolkit -The Translation and Serialization Tookkil (Taskit) is a library that was created to faciliate converting from various input files into Java Objects. This is espcially useful for Simulation Models such as [GCM](https://github.com/HHS/ASPR-8). +The Translation and Serialization Toolkit (Taskit) is a library that was created to facilitate converting from various input files into Java Objects. This is especially useful for Simulation Models such as [GCM](https://github.com/HHS/ASPR-8). -Currently there is only 1 supported serialzation format, and that is protobuf. Other formats such as binary will follow in the future. +Currently there is only 1 supported serialization format, and that is protobuf. Other formats such as binary will follow in the future. As of v3.2.0, this project is in Maven Central. ## License Distributed under the GPLv3 License. See [LICENSE](LICENSE) for more information. -Please read the [HHS vulnerability discloure](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). +Please read the [HHS vulnerability disclosure](https://www.hhs.gov/vulnerability-disclosure-policy/index.html). ## Usage To use this project in your project, simply add the following dependency to your `dependencies` section of your pom.xml file. @@ -22,7 +22,7 @@ To use this project in your project, simply add the following dependency to your gov.hhs.aspr.ms.taskit core - 4.0.0 + 5.0.0 ``` @@ -31,7 +31,7 @@ To use the protobuf library of taskit, simply add the following dependency to yo gov.hhs.aspr.ms.taskit protobuf - 4.0.0 + 5.0.0 ``` @@ -39,21 +39,26 @@ To use the protobuf library of taskit, simply add the following dependency to yo Currently Taskit is composed of a Core library and a Protobuf library. ### Core -[Core](core) is the base taskit engine and contains the root level functionality that drives the translation and serialization. -This library contains the base TranslationController class, the base TranslationSpec class and the base TranslationEngine class. - -#### TranslationController -The TranslationController class handles the delgation of reading/writing from/to input/output files. +[Core](core) contains TranslationSpec, TaskitEngine, TaskitEngineId, TaskitEngineManager, and Translator. These classes define the root level functionality of Taskit. #### TranslationSpec -The TranslationSpec class is an abstract class that must be impleneted to define how to convert between two Java Types, generally the input Java type and the application Java Type. +An abstract class that defines how to translate between two different Java Types. Implementers of this class must define the intricate details on the translation, while the abstract class strictly handles initialization and determining which internal translate method to call based on the given object that needs to be translated. + +#### TaskitEngine +An abstract class that contains a mapping of classes to TranslationSpecs. It has the sole responsibility of translating/reading/writing. For translating, it will determine which TranslationSpec to use based on the class of the given object to translate. Implementers of this class must define how to read/write files, as that process can vary between serialization libraries. + +#### TaskitEngineId +An identifier for a TaskitEngine, for use in the TaskitEngineManager. + +#### TaskitEngineManager +The TaskitEngineManager can handle multiple TaskitEngines and allows the user to read/write/translate using the TaskitEngineId to determine which TaskitEngine to use. Contains the same methods as TaskitEngine, with an additional parameter for the TaskitEngineId. -#### TranslationEngine -The TranslationEngine class delgates the converting of one type to another via TranslationSpecs as well as doing the actual reading/writing as delegated by the TranslationController. +#### Translator +A Translator is simply a class that can wrap a group of TranslationSpecs that should/will often be used together. It also contains a dependency mechanism that allows for Translators to depend on other Translators, which is useful if a given TranslationSpec requires another TranslationSpec that is not provided by the encompassing Translator. Translators must follow a DAG pattern; there cannot be duplicate Translators, missing Translators nor cyclic Translator dependencies. ### Protobuf [Protobuf](protobuf) is a version of taskit made specifically to be used with protobuf. -This library builds on the Core library described above and adds a distinct TranslationEngine and TranslationSpecs needed to fully support protobuf. +This library builds on the Core library described above and adds a distinct TaskitEngine and TranslationSpecs needed to fully support protobuf. #### Supported types This library supports the following proto message types: diff --git a/core/pom.xml b/core/pom.xml index 8aa6902..ae78a3e 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -11,7 +11,6 @@ - gov.hhs.aspr.ms.taskit core jar diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/BaseTranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/BaseTranslationSpec.java deleted file mode 100644 index 23d4579..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/BaseTranslationSpec.java +++ /dev/null @@ -1,13 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -/** - * Base interface for TranslationSpecifications (TranslationSpecs) Package level - * access - */ -interface BaseTranslationSpec { - void init(T translationEngine); - - T convert(Object object); - - boolean isInitialized(); -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/CoreTranslationError.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/CoreTranslationError.java deleted file mode 100644 index 4fd400f..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/CoreTranslationError.java +++ /dev/null @@ -1,51 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import gov.hhs.aspr.ms.util.errors.ContractError; - -public enum CoreTranslationError implements ContractError { - - CIRCULAR_TRANSLATOR_DEPENDENCIES("Circular translator dependencies: "), - DUPLICATE_CLASSREF("Duplicate ClassRef"), - DUPLICATE_DEPENDENCY("Duplicate Dependency"), - DUPLICATE_INPUT_PATH("Duplicate Input Path"), - DUPLICATE_TRANSLATOR("Duplicate Translator"), - DUPLICATE_TRANSLATION_SPEC("Duplicate TranslationSpec"), - INVALID_INPUT_PATH("The given input file path does not exist"), - INVALID_OUTPUT_PATH( - "The given output file path does not exist. While the file will be created on write, the directory will not."), - INVALID_TRANSLATION_ENGINE_BUILDER_CLASS_REF( - "The given Translation Engine Builder classRef does not match the class of the actual Translation Engine Builder"), - MISSING_TRANSLATOR("Missing Translator: "), - NO_TRANSLATION_ENGINES("There are no translation engines added to this controller."), - NULL_CLASS_REF("Null Class Ref"), - NULL_DEPENDENCY("Null dependency"), - NULL_INIT_CONSUMER("Null Initializer Consumer"), - NULL_OBJECT_FOR_TRANSLATION("The object to be translated was null"), - NULL_PATH("Null Path"), - NULL_TRANSLATION_ENGINE("Null Translation Engine"), - NULL_TRANSLATION_ENGINE_BUILDER("Null Translation Engine Builder"), - NULL_TRANSLATION_SPEC("Null TranslationSpec"), - NULL_TRANSLATION_SPEC_APP_CLASS("Null TranslationSpec App Class"), - NULL_TRANSLATION_SPEC_INPUT_CLASS("Null TranslationSpec Input Class"), - NULL_TRANSLATOR("Null Translator"), - NULL_TRANSLATOR_ID("Null TranslatorId"), - UNINITIALIZED_TRANSLATION_SPEC("TranslationSpec not initialized"), - UNINITIALIZED_TRANSLATORS( - "Translators were added to the builder but were not initialized. Make sure to call super.initTranslators() during your custom engine build method"), - UNKNOWN_CLASSREF("No object has been read in with the specified classRef"), - UNKNOWN_OBJECT("Object is not Translatable by this TranslationSpec"), - UNKNOWN_TRANSLATION_ENGINE_TYPE("Translation Engine Type was not set"), - UNKNOWN_TRANSLATION_SPEC("No translation spec was provided for the given class"), - UNSUPPORTED_VERSION("The given version is not supported"); - - private final String description; - - private CoreTranslationError(final String description) { - this.description = description; - } - - @Override - public String getDescription() { - return description; - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationController.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationController.java deleted file mode 100644 index 46a5e72..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationController.java +++ /dev/null @@ -1,471 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import gov.hhs.aspr.ms.util.errors.ContractException; - -/** - * The TranslatorController serves as the master of ceremonies for translating - * between two types of objects. Additionally, it has the ability to distribute - * Input/Output files for reading and writing. - */ -public final class TranslationController { - protected final Data data; - protected final Map translationEngines = new LinkedHashMap<>(); - protected final Map, TranslationEngineType> translationEngineClassToTypeMap = new LinkedHashMap<>(); - protected final List objects = Collections.synchronizedList(new ArrayList<>()); - - TranslationController(Data data) { - this.data = data; - } - - final static class Data { - protected Set translationEngines = new LinkedHashSet<>(); - protected final List translators = new ArrayList<>(); - protected final Map> inputFilePathMap = new LinkedHashMap<>(); - protected final Map inputFilePathEngine = new LinkedHashMap<>(); - protected final Map, Class> parentChildClassRelationshipMap = new LinkedHashMap<>(); - - Data() { - } - } - - public final static class Builder { - Data data; - - Builder(Data data) { - this.data = data; - } - - private void validateClassRefNotNull(Class classRef) { - if (classRef == null) { - throw new ContractException(CoreTranslationError.NULL_CLASS_REF); - } - } - - private void validateFilePathNotNull(Path filePath) { - if (filePath == null) { - throw new ContractException(CoreTranslationError.NULL_PATH); - } - } - - private void validatePathNotDuplicate(Path filePath) { - if (this.data.inputFilePathMap.containsKey(filePath)) { - throw new ContractException(CoreTranslationError.DUPLICATE_INPUT_PATH); - } - } - - private void validateTranslationEngineNotNull(TranslationEngine translationEngine) { - if (translationEngine == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_ENGINE); - } - } - - private void validateTranslationEnginesNotNull() { - if (this.data.translationEngines.isEmpty()) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_ENGINE, - "No TranslationEngine Builders were added"); - } - for (TranslationEngine engine : this.data.translationEngines) { - validateTranslationEngineNotNull(engine); - } - } - - /** - * Builds the TranslatorController. Calls the initializer on each added - * {@link Translator} - * - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_ENGINE} - * if translationEngineBuilder has not been set
  • - *
- */ - public TranslationController build() { - validateTranslationEnginesNotNull(); - - TranslationController translatorController = new TranslationController(this.data); - - translatorController.initTranslationEngines(); - translatorController.validateTranslationEngines(); - - return translatorController; - } - - TranslationController buildWithoutInitAndChecks() { - return new TranslationController(this.data); - } - - /** - * Adds the path and class ref to be read from after building via - * {@link TranslationController#readInput()} - * - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_PATH} if - * filePath is null
  • - *
  • {@linkplain CoreTranslationError#NULL_CLASS_REF} - * if classRef is null
  • - *
  • {@linkplain CoreTranslationError#DUPLICATE_INPUT_PATH} - * if filePath has already been added
  • - *
  • {@linkplain CoreTranslationError#INVALID_INPUT_PATH} - * if filePath does not exist on the system
  • - *
- */ - public Builder addInputFilePath(Path filePath, Class classRef, TranslationEngineType translationEngineType) { - validateFilePathNotNull(filePath); - validateClassRefNotNull(classRef); - validatePathNotDuplicate(filePath); - - if (!filePath.toFile().exists()) { - throw new ContractException(CoreTranslationError.INVALID_INPUT_PATH); - } - - this.data.inputFilePathMap.put(filePath, classRef); - this.data.inputFilePathEngine.put(filePath, translationEngineType); - return this; - } - - /** - * Adds the given classRef markerInterface mapping. - *

- * explicitly used when calling {@link TranslationController#writeOutput} with a - * class for which a classRef ScenarioId pair does not exist and/or the need to - * output the given class as the markerInterface instead of the concrete class - * - * @param the childClass - * @param the parentClass/MarkerInterfaceClass - * @throws ContractException - *

    - *
  • {@linkplain CoreTranslationError#NULL_CLASS_REF} - * if classRef is null or if markerInterface is - * null
  • - *
  • {@linkplain CoreTranslationError#DUPLICATE_CLASSREF} - * if child parent relationship has already been - * added
  • - *
- */ - public Builder addParentChildClassRelationship(Class classRef, Class parentClassRef) { - validateClassRefNotNull(classRef); - validateClassRefNotNull(parentClassRef); - - if (this.data.parentChildClassRelationshipMap.containsKey(classRef)) { - throw new ContractException(CoreTranslationError.DUPLICATE_CLASSREF); - } - - this.data.parentChildClassRelationshipMap.put(classRef, parentClassRef); - return this; - } - - /** - * Adds a {@link TranslationEngine.Builder} - * - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_ENGINE} - * if translationEngineBuilder is null
  • - *
- */ - public Builder addTranslationEngine(TranslationEngine translationEngine) { - validateTranslationEngineNotNull(translationEngine); - - this.data.translationEngines.add(translationEngine); - - Map, Class> childToParentClassMap = translationEngine.getChildParentClassMap(); - - for (Class childClassRef : childToParentClassMap.keySet()) { - // Need to duplicate code here because the map doesn't provide the type safety - // that is required by the addParentChildClassRelationship method - Class parentClassRef = childToParentClassMap.get(childClassRef); - - // Note: no 'class is not null' validation here because it was validated prior - // to being put into the engine - if (this.data.parentChildClassRelationshipMap.containsKey(childClassRef)) { - throw new ContractException(CoreTranslationError.DUPLICATE_CLASSREF); - } - - this.data.parentChildClassRelationshipMap.put(childClassRef, parentClassRef); - } - - return this; - } - } - - /** - * Returns a new instance of Builder - */ - public static Builder builder() { - return new Builder(new Data()); - } - - void initTranslationEngines() { - for (TranslationEngine translationEngine : this.data.translationEngines) { - translationEngine.translationSpecsAreInitialized(); - - this.translationEngines.put(translationEngine.getTranslationEngineType(), translationEngine); - this.translationEngineClassToTypeMap.put(translationEngine.getClass(), - translationEngine.getTranslationEngineType()); - } - - // since we are making a new mapping, clear the original set in the data - this.data.translationEngines.clear(); - } - - void validateTranslationEngine(TranslationEngine translationEngine) { - if (translationEngine == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_ENGINE); - } - - /* - * Because the translationEngine's init method is called within the - * initTranslators() method, this should never happen, thus it is a - * RuntimeException and not a ContractException - */ - if (!translationEngine.isInitialized()) { - throw new RuntimeException("TranslationEngine has been built but has not been initialized."); - } - } - - void validateTranslationEngines() { - Set> translationEngineClasses = new HashSet<>(); - - if (this.translationEngines.keySet().isEmpty()) { - throw new ContractException(CoreTranslationError.NO_TRANSLATION_ENGINES); - } - - // validate each engine that exists irrespective of any mapping - for (TranslationEngine translationEngine : this.translationEngines.values()) { - validateTranslationEngine(translationEngine); - translationEngineClasses.add(translationEngine.getClass()); - } - - // if the class to type map doesn't contain all of the classes of the engines in - // the engine map - // and - // if the engine map doesn't contain all of the types from the class to type map - // this ensures that every engine has a valid class -> type -> engine mapping - if (!(this.translationEngineClassToTypeMap.keySet().containsAll(translationEngineClasses) - && this.translationEngines.keySet().containsAll(this.translationEngineClassToTypeMap.values()))) { - throw new RuntimeException( - "Not all Translation Engines have an associated Class -> Type -> Engine Mapping. Something went very wrong."); - } - } - - /** - * passes every input path and classRef to - * the TranslationEngine via - * {@link TranslationController#readInput(Path, Class, TranslationEngine)} - */ - public TranslationController readInput() { - for (Path path : this.data.inputFilePathMap.keySet()) { - Class classRef = this.data.inputFilePathMap.get(path); - TranslationEngineType type = this.data.inputFilePathEngine.get(path); - TranslationEngine translationEngine = this.translationEngines.get(type); - - this.readInput(path, classRef, translationEngine); - } - - return this; - } - - /** - * Passes the given reader and inputClassRef to the built - * {@link TranslationEngine} to read, parse and translate the inputData. - * - * @param the classType associated with the reader - */ - void readInput(Path path, Class inputClassRef, TranslationEngine translationEngine) { - Object appObject; - try { - appObject = translationEngine.readInput(path, inputClassRef); - this.objects.add(appObject); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * writes the given object to the given path using the given translation engine - * type - * - * @param the classType of the object - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_OBJECT_FOR_TRANSLATION} - * if the object is null
  • - *
  • {@linkplain CoreTranslationError#NULL_PATH} - * if the path is null
  • - *
  • {@linkplain CoreTranslationError#INVALID_OUTPUT_PATH} - * if the path does not exist (specifically the parent - * directory of the path ie. a/b/c/foo.txt throws this - * if a/b/c doesn't exist
  • - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_ENGINE} - * if translationEngine is null
  • - *
- */ - public void writeOutput(M object, Path path, - TranslationEngineType translationEngineType) { - - Optional> parentClassRef = Optional.empty(); - - if (this.data.parentChildClassRelationshipMap.containsKey(object.getClass())) { - // can safely cast because of type checking when adding to the - // parentChildClassRelationshipMap - @SuppressWarnings("unchecked") - Class parentClass = (Class) this.data.parentChildClassRelationshipMap.get(object.getClass()); - - parentClassRef = Optional.of(parentClass); - } - this.writeOutput(object, parentClassRef, path, translationEngineType); - } - - /** - * writes the given object to the given path using the given translation engine - * type using the parent class as the actual output type - * - * @param the classType of the object - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_CLASS_REF} - * if the parent classref is null
  • - *
  • {@linkplain CoreTranslationError#NULL_OBJECT_FOR_TRANSLATION} - * if the object is null
  • - *
  • {@linkplain CoreTranslationError#NULL_PATH} - * if the path is null
  • - *
  • {@linkplain CoreTranslationError#INVALID_OUTPUT_PATH} - * if the path does not exist (specifically the parent - * directory of the path ie. a/b/c/foo.txt throws this - * if a/b/c doesn't exist
  • - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_ENGINE} - * if translationEngine is null
  • - *
- */ - public void writeOutput(M object, Class parentClassRef, Path path, - TranslationEngineType translationEngineType) { - - if (parentClassRef == null) { - throw new ContractException(CoreTranslationError.NULL_CLASS_REF); - } - - this.writeOutput(object, Optional.of(parentClassRef), path, translationEngineType); - } - - void writeOutput(M object, Optional> parentClassRef, Path path, - TranslationEngineType translationEngineType) { - - if (object == null) { - throw new ContractException(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION); - } - - if (path == null) { - throw new ContractException(CoreTranslationError.NULL_PATH); - } - - if (!path.getParent().toFile().exists()) { - throw new ContractException(CoreTranslationError.INVALID_OUTPUT_PATH); - } - - TranslationEngine translationEngine = this.translationEngines.get(translationEngineType); - - if (translationEngine == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_ENGINE); - } - - this.writeOutput(path, object, parentClassRef, translationEngine); - } - - /** - * Passes the given writer object and optional superClass to the built - * {@link TranslationEngine} to translate and write to the outputFile - * - * @param the class of the object to write to the outputFile - * @param the optional parent class of the object to write to the outputFile - */ - void writeOutput(Path path, M object, Optional> superClass, - TranslationEngine translationEngine) { - try { - translationEngine.writeOutput(path, object, superClass); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Searches the list of read in objects and returns the first Object found of - * the given classRef - * - * @param the type of the object to get - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#UNKNOWN_CLASSREF} - * if no object with the specified class is found
  • - *
- */ - public T getFirstObject(Class classRef) { - int index = -1; - for (int i = 0; i < this.objects.size(); i++) { - Object object = this.objects.get(i); - - if (classRef.isAssignableFrom(object.getClass())) { - index = i; - break; - } - - } - - if (index > -1) { - return classRef.cast(this.objects.remove(index)); - } - - throw new ContractException(CoreTranslationError.UNKNOWN_CLASSREF); - } - - /** - * Searches the list of read in objects and returns all Objects found with the - * given classRef - * - * @param the type of the object to get - */ - public List getObjects(Class classRef) { - List objects = new ArrayList<>(); - for (int i = 0; i < this.objects.size(); i++) { - Object object = this.objects.get(i); - - if (classRef.isAssignableFrom(object.getClass())) { - objects.add(classRef.cast(object)); - } - - } - - this.objects.removeAll(objects); - - return objects; - } - - /** - * Returns the entire list of read in objects - */ - public List getObjects() { - List objects = new ArrayList<>(this.objects); - - this.objects.clear(); - - return objects; - } - - // package access for testing - int getNumObjects() { - return this.objects.size(); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationEngine.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationEngine.java deleted file mode 100644 index 6f81648..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationEngine.java +++ /dev/null @@ -1,626 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import gov.hhs.aspr.ms.util.errors.ContractException; -import gov.hhs.aspr.ms.util.graph.Graph; -import gov.hhs.aspr.ms.util.graph.GraphDepthEvaluator; -import gov.hhs.aspr.ms.util.graph.Graphs; -import gov.hhs.aspr.ms.util.graph.MutableGraph; - -/** - * Main Translator Class Initializes all {@link TranslationSpec}s and maintains - * a mapping between the translationSpec and it's respective classes This is an - * Abstract class, meaning that for a given translation library (Fasterxml, - * Protobuf, etc) must have a custom implemented TranslationEngine - */ -public abstract class TranslationEngine { - - private final Data data; - protected boolean debug = false; - protected boolean isInitialized = false; - - protected TranslationEngine(Data data) { - this.data = data; - } - - protected static class Data { - protected final Map, BaseTranslationSpec> classToTranslationSpecMap = new LinkedHashMap<>(); - protected final Set translationSpecs = new LinkedHashSet<>(); - protected Map, Class> childToParentClassMap = new LinkedHashMap<>(); - protected TranslationEngineType translationEngineType = TranslationEngineType.UNKNOWN; - protected boolean translatorsInitialized = false; - - protected Data() { - } - - @Override - public int hashCode() { - return Objects.hash(classToTranslationSpecMap, translationSpecs); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Data other = (Data) obj; - - if (!Objects.equals(classToTranslationSpecMap, other.classToTranslationSpecMap)) { - return false; - } - - if (!Objects.equals(translationSpecs, other.translationSpecs)) { - return false; - } - - return true; - - } - - } - - /** - * This class contains protected final methods for all of its abstract methods. - * All descendant classes of this class MUST call these if you want it to - * function properly. - */ - public abstract static class Builder { - protected Data data; - protected final List translators = new ArrayList<>(); - - protected Builder(Data data) { - this.data = data; - } - - private void validateTranslationSpec(TranslationSpec translationSpec) { - if (translationSpec == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_SPEC); - } - - if (translationSpec.getAppObjectClass() == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_SPEC_APP_CLASS); - } - - if (translationSpec.getInputObjectClass() == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATION_SPEC_INPUT_CLASS); - } - - if (this.data.translationSpecs.contains(translationSpec)) { - throw new ContractException(CoreTranslationError.DUPLICATE_TRANSLATION_SPEC); - } - } - - private void validateTranslatorNotNull(Translator translator) { - if (translator == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATOR); - } - } - - private void validateClassRefNotNull(Class classRef) { - if (classRef == null) { - throw new ContractException(CoreTranslationError.NULL_CLASS_REF); - } - } - - void clearBuilder() { - this.data = new Data(); - } - - /** - * Builder for the TranslationEngine - */ - public abstract TranslationEngine build(); - - protected final void initTranslators() { - TranslatorContext translatorContext = new TranslatorContext(this); - - List orderedTranslators = this.getOrderedTranslators(); - - for (Translator translator : orderedTranslators) { - translator.getInitializer().accept(translatorContext); - } - - this.data.translatorsInitialized = true; - this.translators.clear(); - } - - /** - * Adds the given {@link TranslationSpec} to the internal - * classToTranslationSpecMap - * - * @param the input object type - * @param the app object type - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_SPEC} - * if the given translationSpec is null
  • - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_SPEC_APP_CLASS} - * if the given translationSpecs getAppClass method - * returns null
  • - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATION_SPEC_INPUT_CLASS} - * if the given translationSpecs getInputClass method - * returns null
  • - *
  • {@linkplain CoreTranslationError#DUPLICATE_TRANSLATION_SPEC} - * if the given translationSpec is already known
  • - *
- */ - public abstract Builder addTranslationSpec(TranslationSpec translationSpec); - - protected final void _addTranslationSpec(TranslationSpec translationSpec) { - validateTranslationSpec(translationSpec); - - this.data.classToTranslationSpecMap.put(translationSpec.getInputObjectClass(), translationSpec); - this.data.classToTranslationSpecMap.put(translationSpec.getAppObjectClass(), translationSpec); - - this.data.translationSpecs.add(translationSpec); - } - - /** - * Add a {@link Translator} - * - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATOR} - * if translator is null
  • - *
  • {@linkplain CoreTranslationError#DUPLICATE_TRANSLATOR} - * if translator has already been added
  • - *
- */ - public abstract Builder addTranslator(Translator translator); - - protected final void _addTranslator(Translator translator) { - validateTranslatorNotNull(translator); - - if (this.translators.contains(translator)) { - throw new ContractException(CoreTranslationError.DUPLICATE_TRANSLATOR); - } - - this.translators.add(translator); - } - - /** - * Adds the given classRef markerInterface mapping. - *

- * explicitly used when calling {@link TranslationController#writeOutput} with a - * class for which a classRef ScenarioId pair does not exist and/or the need to - * output the given class as the markerInterface instead of the concrete class - * - * @param the childClass - * @param the parentClass/MarkerInterfaceClass - * @throws ContractException - *

    - *
  • {@linkplain CoreTranslationError#NULL_CLASS_REF} - * if classRef is null or if markerInterface is - * null
  • - *
  • {@linkplain CoreTranslationError#DUPLICATE_CLASSREF} - * if child parent relationship has already been - * added
  • - *
- */ - public abstract Builder addParentChildClassRelationship(Class classRef, - Class parentClassRef); - - protected final void _addParentChildClassRelationship(Class classRef, - Class parentClassRef) { - validateClassRefNotNull(classRef); - validateClassRefNotNull(parentClassRef); - - if (this.data.childToParentClassMap.containsKey(classRef)) { - throw new ContractException(CoreTranslationError.DUPLICATE_CLASSREF); - } - - this.data.childToParentClassMap.put(classRef, parentClassRef); - } - - /* - * Goes through the list of translators and orders them based on their - * dependencies - */ - List getOrderedTranslators() { - return this.getOrderedTranslators(new MutableGraph<>(), new LinkedHashMap<>()); - } - - /* - * Goes through the list of translators and orders them based on their - * dependencies - */ - List getOrderedTranslators(MutableGraph mutableGraph, - Map translatorMap) { - - /* - * Add the nodes to the graph, check for duplicate ids, build the mapping from - * plugin id back to plugin - */ - this.addNodes(mutableGraph, translatorMap); - - // Add the edges to the graph - this.addEdges(mutableGraph); - - /* - * Check for missing plugins from the plugin dependencies that were collected - * from the known plugins. - */ - checkForMissingTranslators(mutableGraph, translatorMap); - - /* - * Determine whether the graph is acyclic and generate a graph depth evaluator - * for the graph so that we can determine the order of initialization. - */ - checkForCyclicGraph(mutableGraph); - - // the graph is acyclic, so the depth evaluator is present - GraphDepthEvaluator graphDepthEvaluator = GraphDepthEvaluator - .getGraphDepthEvaluator(mutableGraph.toGraph()).get(); - - List orderedTranslatorIds = graphDepthEvaluator.getNodesInRankOrder(); - - List orderedTranslators = new ArrayList<>(); - for (TranslatorId translatorId : orderedTranslatorIds) { - orderedTranslators.add(translatorMap.get(translatorId)); - } - - return orderedTranslators; - } - - void addNodes(MutableGraph mutableGraph, Map translatorMap) { - TranslatorId focalTranslatorId = null; - for (Translator translator : this.translators) { - focalTranslatorId = translator.getTranslatorId(); - translatorMap.put(focalTranslatorId, translator); - // ensure that there are no duplicate plugins - if (mutableGraph.containsNode(focalTranslatorId)) { - throw new ContractException(CoreTranslationError.DUPLICATE_TRANSLATOR); - } - mutableGraph.addNode(focalTranslatorId); - focalTranslatorId = null; - } - } - - void addEdges(MutableGraph mutableGraph) { - TranslatorId focalTranslatorId = null; - for (Translator translator : this.translators) { - focalTranslatorId = translator.getTranslatorId(); - for (TranslatorId translatorId : translator.getTranslatorDependencies()) { - mutableGraph.addEdge(new Object(), focalTranslatorId, translatorId); - } - focalTranslatorId = null; - } - } - - void checkForMissingTranslators(MutableGraph mutableGraph, - Map translatorMap) { - for (TranslatorId translatorId : mutableGraph.getNodes()) { - if (!translatorMap.containsKey(translatorId)) { - List inboundEdges = mutableGraph.getInboundEdges(translatorId); - StringBuilder sb = new StringBuilder(); - sb.append("cannot locate instance of "); - sb.append(translatorId); - sb.append(" needed for "); - boolean first = true; - for (Object edge : inboundEdges) { - if (first) { - first = false; - } else { - sb.append(", "); - } - TranslatorId dependentTranslatorId = mutableGraph.getOriginNode(edge); - sb.append(dependentTranslatorId); - } - throw new ContractException(CoreTranslationError.MISSING_TRANSLATOR, sb.toString()); - } - } - } - - void checkForCyclicGraph(MutableGraph mutableGraph) { - Optional> optional = GraphDepthEvaluator - .getGraphDepthEvaluator(mutableGraph.toGraph()); - - if (!optional.isPresent()) { - /* - * Explain in detail why there is a circular dependency - */ - - Graph g = mutableGraph.toGraph(); - g = Graphs.getSourceSinkReducedGraph(g); - g = Graphs.getEdgeReducedGraph(g); - g = Graphs.getSourceSinkReducedGraph(g); - - List> cutGraphs = Graphs.cutGraph(g); - StringBuilder sb = new StringBuilder(); - String lineSeparator = System.getProperty("line.separator"); - sb.append(lineSeparator); - boolean firstCutGraph = true; - - for (Graph cutGraph : cutGraphs) { - if (firstCutGraph) { - firstCutGraph = false; - } else { - sb.append(lineSeparator); - } - sb.append("Dependency group: "); - sb.append(lineSeparator); - Set nodes = cutGraph.getNodes().stream() - .collect(Collectors.toCollection(LinkedHashSet::new)); - - for (TranslatorId node : nodes) { - sb.append("\t"); - sb.append(node); - sb.append(" requires:"); - sb.append(lineSeparator); - for (Object edge : cutGraph.getInboundEdges(node)) { - TranslatorId dependencyNode = cutGraph.getOriginNode(edge); - sb.append("\t"); - sb.append("\t"); - sb.append(dependencyNode); - sb.append(lineSeparator); - } - } - } - throw new ContractException(CoreTranslationError.CIRCULAR_TRANSLATOR_DEPENDENCIES, sb.toString()); - } - } - } - - private void validateTranslationEngineType() { - if (this.data.translationEngineType == TranslationEngineType.UNKNOWN) { - throw new ContractException(CoreTranslationError.UNKNOWN_TRANSLATION_ENGINE_TYPE); - } - } - - private void validateTranslatorsInitialized() { - if (!this.data.translatorsInitialized) { - throw new ContractException(CoreTranslationError.UNINITIALIZED_TRANSLATORS); - } - } - - // This is package access so the TranslationController can access it but nothing - // else. - Map, Class> getChildParentClassMap() { - Map, Class> copyMap = new LinkedHashMap<>(this.data.childToParentClassMap); - - return copyMap; - } - - /** - * returns the {@link TranslationEngineType} of this TranslationEngine - * - * guaranteed to NOT be {@link TranslationEngineType#UNKNOWN} - */ - public TranslationEngineType getTranslationEngineType() { - return this.data.translationEngineType; - } - - /** - * Initializes the translationEngine by calling init on each translationSpec - * added in the builder - */ - protected void initTranslationSpecs() { - /* - * Calling init on a translationSpec causes the hashCode of the translationSpec - * to change. Because of this, before calling init, we need to remove them from - * the translationSpecs Set then initialize them, then add them back to the set. - * Set's aren't happy when the hash code of the objects in them change - */ - List copyOfTranslationSpecs = new ArrayList<>(this.data.translationSpecs); - - this.data.translationSpecs.clear(); - - for (BaseTranslationSpec translationSpec : copyOfTranslationSpecs) { - translationSpec.init(this); - this.data.translationSpecs.add(translationSpec); - } - - this.isInitialized = true; - } - - protected void validateInit() { - validateTranslationEngineType(); - validateTranslatorsInitialized(); - } - - /** - * returns whether this translationEngine is initialized or not - */ - public boolean isInitialized() { - return this.isInitialized; - } - - /** - * checks to verify all the translationSpecs have been initialized. - * - * @throws RuntimeException There should not be a case where all - * translationSpecs are initialized, so if one of them - * isn't, something went very wrong. - */ - protected void translationSpecsAreInitialized() { - - for (BaseTranslationSpec translationSpec : this.data.translationSpecs) { - if (!translationSpec.isInitialized()) { - throw new RuntimeException(translationSpec.getClass().getName() - + " was not properly initialized, be sure to call super()"); - } - } - - } - - /** - * Returns a set of all {@link TranslationSpec}s associated with this - * TranslationEngine - */ - public Set getTranslationSpecs() { - return this.data.translationSpecs; - } - - /** - * abstract method that must be implemented by child TranslatorCores that - * defines how to write to output files - */ - protected abstract void writeOutput(Path path, M appObject, Optional> superClass) - throws IOException; - - /** - * abstract method that must be implemented by child TranslatorCores that - * defines how to read from input files - */ - protected abstract T readInput(Path path, Class inputClassRef) throws IOException; - - /** - * Given an object, uses the class of the object to obtain the translationSpec - * and then calls {@link TranslationSpec#convert(Object)} - *

- * this conversion method will be used approx ~90% of the time - *

- * - * @param the return type after converting - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_OBJECT_FOR_TRANSLATION} - * if the passed in object is null
  • - *
  • {@linkplain CoreTranslationError#UNKNOWN_TRANSLATION_SPEC} - * if no translationSpec was provided for the given - * objects class
  • - *
- */ - public T convertObject(Object object) { - if (object == null) { - throw new ContractException(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION); - } - return getTranslationSpecForClass(object.getClass()).convert(object); - } - - /** - * Given an object, uses the parent class of the object to obtain the - * translationSpec and then calls {@link TranslationSpec#convert(Object)} - *

- * This method call is safe in the sense that the type parameters ensure that - * the passed in object is actually a child of the passed in parentClassRef - *

- *

- * this conversion method will be used approx ~7% of the time - *

- * - * @param the return type after converting - * @param the type of the object; extends U - * @param the parent type of the object and the class for which - * translationSpec you want to use - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_OBJECT_FOR_TRANSLATION} - * if the passed in object is null
  • - *
  • {@linkplain CoreTranslationError#NULL_CLASS_REF} - * if the passed in parentClassRef is null
  • - *
  • {@linkplain CoreTranslationError#UNKNOWN_TRANSLATION_SPEC} - * if no translationSpec was provided for the given - * objects class
  • - *
- */ - public T convertObjectAsSafeClass(M object, Class parentClassRef) { - if (object == null) { - throw new ContractException(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION); - } - - if (parentClassRef == null) { - throw new ContractException(CoreTranslationError.NULL_CLASS_REF); - } - - return getTranslationSpecForClass(parentClassRef).convert(object); - } - - /** - * Given an object, uses the passed in class to obtain the translationSpec and - * then calls {@link TranslationSpec#convert(Object)} - *

- * This method call is unsafe in the sense that the type parameters do not - * ensure any relationship between the passed in object and the passed in - * classRef. - *

- *

- * A common use case for using this conversion method would be to call a - * translationSpec that will wrap the given object in another object. - *

- *

- * this conversion method will be used approx ~3% of the time - *

- * - * @param the return type after converting - * @param the type of the object - * @param the type of the class for which translationSpec you want to use - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_OBJECT_FOR_TRANSLATION} - * if the passed in object is null
  • - *
  • {@linkplain CoreTranslationError#NULL_CLASS_REF} - * if the passed in objectClassRef is null
  • - *
  • {@linkplain CoreTranslationError#UNKNOWN_TRANSLATION_SPEC} - * if no translationSpec was provided for the given - * objects class
  • - *
- */ - public T convertObjectAsUnsafeClass(M object, Class objectClassRef) { - if (object == null) { - throw new ContractException(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION); - } - - if (objectClassRef == null) { - throw new ContractException(CoreTranslationError.NULL_CLASS_REF); - } - - return getTranslationSpecForClass(objectClassRef).convert(object); - } - - /** - * Given a classRef, returns the translationSpec associated with that class, if - * it is known - * - * @throws ContractException {@linkplain CoreTranslationError#UNKNOWN_TRANSLATION_SPEC} - * if no translationSpec for the given class was found - */ - protected BaseTranslationSpec getTranslationSpecForClass(Class classRef) { - if (this.data.classToTranslationSpecMap.containsKey(classRef)) { - return this.data.classToTranslationSpecMap.get(classRef); - } - throw new ContractException(CoreTranslationError.UNKNOWN_TRANSLATION_SPEC, classRef.getName()); - } - - @Override - public int hashCode() { - return Objects.hash(data, isInitialized); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TranslationEngine other = (TranslationEngine) obj; - - if (isInitialized != other.isInitialized) { - return false; - } - return Objects.equals(data, other.data); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationEngineType.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationEngineType.java deleted file mode 100644 index 70957dc..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationEngineType.java +++ /dev/null @@ -1,7 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -public enum TranslationEngineType { - PROTOBUF, - CUSTOM, - UNKNOWN -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationSpec.java deleted file mode 100644 index f84c627..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslationSpec.java +++ /dev/null @@ -1,139 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import java.util.Objects; - -import gov.hhs.aspr.ms.util.errors.ContractException; - -/** - * Core implementation of the {@link BaseTranslationSpec} that must be - * implemented by each needed translationSpec. - *

- * Note: No reference to a {@link TranslationEngine} exists in this class, and - * must be implemented by the implementing class. - */ -public abstract class TranslationSpec implements BaseTranslationSpec { - private boolean initialized = false; - - /** - * Initializes this translationSpec. All child TranslationSpecs must call - * super() otherwise there will be an exception throw in the TranslationEngine - */ - public void init(T translationEngine) { - this.initialized = true; - } - - /** - * Returns the initialization state of this TranslationSpec - */ - public boolean isInitialized() { - return this.initialized; - } - - /** - * The implementation of the {@link BaseTranslationSpec#convert(Object)} method - * Given the object, determines which method should be called. - *

- * It first checks if the object class is exactly equal to either the App or - * Input Class and if so, calls the related method - *

- *

- * It then checks if the the object class is assignable from either the App or - * Input Class and if so, calls the related method - *

- *

- * If no match can be found, an exception is thrown - *

- * - * @param the expected return type after translation/conversion - * @throws ContractException {@linkplain CoreTranslationError#UNKNOWN_OBJECT} if - * no match can be found between the passed in object - * and the given appClass and InputClass - */ - @SuppressWarnings("unchecked") - public T convert(Object obj) { - checkInit(); - - if ((this.getAppObjectClass() == obj.getClass())) { - return (T) this.convertAppObject((A) obj); - } - - if ((this.getInputObjectClass() == obj.getClass())) { - return (T) this.convertInputObject((I) obj); - } - - if ((this.getAppObjectClass().isAssignableFrom(obj.getClass()))) { - return (T) this.convertAppObject((A) obj); - } - - if ((this.getInputObjectClass().isAssignableFrom(obj.getClass()))) { - return (T) this.convertInputObject((I) obj); - } - - throw new ContractException(CoreTranslationError.UNKNOWN_OBJECT, "Object is not a " - + this.getAppObjectClass().getName() + " and it is not a " + this.getInputObjectClass().getName()); - - } - - @Override - public int hashCode() { - return Objects.hash(initialized, getAppObjectClass(), getInputObjectClass()); - } - - @Override - public boolean equals(Object obj) { - // if same object, then equal - if (this == obj) { - return true; - } - // if obj is null, not equal - if (obj == null) { - return false; - } - // if obj is not an instance of TranslationSpec, not equal - if (!(obj instanceof TranslationSpec)) { - return false; - } - - @SuppressWarnings("rawtypes") - TranslationSpec other = (TranslationSpec) obj; - - // if different app class, not equal - if (getAppObjectClass() != other.getAppObjectClass()) { - return false; - } - - // if different input class, not equal - if (getInputObjectClass() != other.getInputObjectClass()) { - return false; - } - - // if not both initialized, not equal - return initialized == other.initialized; - } - - /** - * Given an inputObject, converts it to it's appObject equivalent - */ - protected abstract A convertInputObject(I inputObject); - - /** - * Given an appObject, converts it to it's inputObject equivalent - */ - protected abstract I convertAppObject(A appObject); - - /** - * Returns the class of the app object - */ - public abstract Class getAppObjectClass(); - - /** - * Returns the class of the input object - */ - public abstract Class getInputObjectClass(); - - void checkInit() { - if (!this.initialized) { - throw new ContractException(CoreTranslationError.UNINITIALIZED_TRANSLATION_SPEC); - } - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/Translator.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/Translator.java deleted file mode 100644 index 656925e..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/Translator.java +++ /dev/null @@ -1,193 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import java.util.LinkedHashSet; -import java.util.Objects; -import java.util.Set; -import java.util.function.Consumer; - -import gov.hhs.aspr.ms.util.errors.ContractException; - -/** - * The Translator class serves as a wrapper around one or more - * {@link BaseTranslationSpec}(s) and assists in adding those translationSpecs - * to the {@link TranslationEngine} - */ -public final class Translator { - private final Data data; - - private Translator(Data data) { - this.data = data; - } - - final static class Data { - private TranslatorId translatorId; - private Consumer initializer; - private final Set dependencies = new LinkedHashSet<>(); - - Data() { - } - - @Override - public int hashCode() { - return Objects.hash(translatorId, dependencies); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Data other = (Data) obj; - return Objects.equals(translatorId, other.translatorId) && Objects.equals(dependencies, other.dependencies); - } - - } - - public final static class Builder { - private Data data; - - private Builder(Data data) { - this.data = data; - } - - private void validate() { - if (this.data.translatorId == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATOR_ID); - } - if (this.data.initializer == null) { - throw new ContractException(CoreTranslationError.NULL_INIT_CONSUMER); - } - } - - /** - * Builds the Translator - * - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_TRANSLATOR_ID} - * if the translatorId was not set
  • - *
  • {@linkplain CoreTranslationError#NULL_INIT_CONSUMER} - * if the initConsumer was not set
  • - *
- */ - public Translator build() { - validate(); - - return new Translator(data); - } - - /** - * Sets the translatorId - * - * @throws ContractException {@linkplain CoreTranslationError#NULL_TRANSLATOR_ID} - * if the translatorId is null - */ - public Builder setTranslatorId(TranslatorId translatorId) { - if (translatorId == null) { - throw new ContractException(CoreTranslationError.NULL_TRANSLATOR_ID); - } - - this.data.translatorId = translatorId; - - return this; - } - - /** - * Sets the initialization callback for the translator - * - * @throws ContractException {@linkplain CoreTranslationError#NULL_INIT_CONSUMER} - * if the initConsumer is null - */ - public Builder setInitializer(Consumer initConsumer) { - if (initConsumer == null) { - throw new ContractException(CoreTranslationError.NULL_INIT_CONSUMER); - } - - this.data.initializer = initConsumer; - - return this; - } - - /** - * Adds the given TranslatorId as a dependency for this Translator - * - * @throws ContractException - *
    - *
  • {@linkplain CoreTranslationError#NULL_DEPENDENCY} - * if the dependency is null
  • - *
  • {@linkplain CoreTranslationError#DUPLICATE_DEPENDENCY} - * if the dependency has already been added
  • - *
- */ - public Builder addDependency(TranslatorId dependency) { - if (dependency == null) { - throw new ContractException(CoreTranslationError.NULL_DEPENDENCY); - } - - if (this.data.dependencies.contains(dependency)) { - throw new ContractException(CoreTranslationError.DUPLICATE_DEPENDENCY); - } - - this.data.dependencies.add(dependency); - - return this; - } - - } - - /** - * Creates a new Builder for a Translator - */ - public static Builder builder() { - return new Builder(new Data()); - } - - /** - * Returns the Initialization Consumer - */ - public Consumer getInitializer() { - return this.data.initializer; - } - - /** - * Returns the TranslatorId - */ - public TranslatorId getTranslatorId() { - return this.data.translatorId; - } - - /** - * Returns the set of Dependencies - */ - public Set getTranslatorDependencies() { - return this.data.dependencies; - } - - @Override - public int hashCode() { - return Objects.hash(data); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - Translator other = (Translator) obj; - // Objects.equals will automatically return if a == b, so not need for check - return Objects.equals(data, other.data); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslatorContext.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslatorContext.java deleted file mode 100644 index 2c42520..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslatorContext.java +++ /dev/null @@ -1,38 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import gov.hhs.aspr.ms.util.errors.ContractException; - -/** - * Context that is used by {@link Translator}s - * - * Note: This class exists because the subclassed TranslationEngine may have - * different build methods than the abstract one, preventing the associated - * consumer that this context is used in from just being a consumer of a - * TranslationEngine.Builder - */ -public final class TranslatorContext { - - private final TranslationEngine.Builder builder; - - public TranslatorContext(final TranslationEngine.Builder builder) { - this.builder = builder; - } - - /** - * Returns an instance of the TranslationEngine Builder - * - * @param the type of the TranslationEngine - * @throws ContractException {@linkplain CoreTranslationError#INVALID_TRANSLATION_ENGINE_BUILDER_CLASS_REF} - * if the given classRef does not match the class or - * the translatorCoreBuilder is null - */ - public T getTranslationEngineBuilder(final Class classRef) { - if (this.builder.getClass().isAssignableFrom(classRef)) { - return classRef.cast(this.builder); - } - - throw new ContractException(CoreTranslationError.INVALID_TRANSLATION_ENGINE_BUILDER_CLASS_REF, - "No Translation Engine Builder was found for the type: " + classRef.getName()); - - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslatorId.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslatorId.java deleted file mode 100644 index 74a5538..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/TranslatorId.java +++ /dev/null @@ -1,19 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -/** - * Used as a {@link Translator} identifier - */ -public interface TranslatorId { - /** - * Implementation consistent with equals() - */ - @Override - public int hashCode(); - - /** - * Two Translator ids are equal if and only if they represent the same - * Translator. Translator ids are generally implemented as static instances. - */ - @Override - public boolean equals(Object obj); -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/ITaskitEngineBuilder.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/ITaskitEngineBuilder.java new file mode 100644 index 0000000..a506544 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/ITaskitEngineBuilder.java @@ -0,0 +1,26 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; + +/** + * Interface for TaskitEngine Builders. + */ +public interface ITaskitEngineBuilder { + + /** + * Adds the given {@link ITranslationSpec} to the TaskitEngine + * + * @param translationSpec the translationSpec to add + * @return the builder instance + */ + public ITaskitEngineBuilder addTranslationSpec(ITranslationSpec translationSpec); + + /** + * Adds the given {@link Translator} to the TaskitEngine + * + * @param translator the translator to add + * @return the builder instance + */ + public ITaskitEngineBuilder addTranslator(Translator translator); +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngine.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngine.java new file mode 100644 index 0000000..6a7bfcf --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngine.java @@ -0,0 +1,435 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.TranslationSpec; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceError; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +/** + * TaskitEngine initializes all {@link TranslationSpec}s and maintains a mapping + * between the translationSpec and it's respective classes. Each serialization + * library must implement its own unique Taskit Engine that extends this engine + */ +public abstract class TaskitEngine { + private final TaskitEngineData data; + private final TaskitEngineId taskitEngineId; + + private boolean isInitialized = false; + + protected TaskitEngine(TaskitEngineData data, TaskitEngineId taskitEngineId) { + this.data = data; + this.taskitEngineId = taskitEngineId; + } + + /** + * Initializes the taskitEngine by calling init on each translationSpec added in + * the builder + */ + public final void init() { + /* + * Calling init on a translationSpec causes the hashCode of the translationSpec + * to change. Because of this, before calling init, we need to remove them from + * the translationSpecs Set, then initialize them, then add them back to the + * set. Set's aren't happy when the hash code of the objects in them change + */ + List copyOfTranslationSpecs = new ArrayList<>(this.data.translationSpecs); + + this.data.translationSpecs.clear(); + + for (ITranslationSpec translationSpec : copyOfTranslationSpecs) { + + translationSpec.init(this); + this.data.translationSpecs.add(translationSpec); + } + + this.isInitialized = true; + } + + /** + * @return the taskitEngineId for this taskitEngine + */ + public final TaskitEngineId getTaskitEngineId() { + return this.taskitEngineId; + } + + /** + * @return the initialized flag of the TaskitEngine + */ + public final boolean isInitialized() { + return this.isInitialized; + } + + /** + * @return a set of all {@link TranslationSpec}s associated with this + * TaskitEngine + */ + public final Set getTranslationSpecs() { + return this.data.translationSpecs; + } + + /** + * Writes the object to the file referenced by the Path + * + * @param the type of the object to write + * @param outputPath the path of the file to write to + * @param outputObject the object to write + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain ResourceError#DIRECTORY_PATH_IS_FILE} + * if path points to a file that doesn't exist and the + * parent path points to a file
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
+ * @throws IOException if there is an issue writing the file + */ + public final void write(Path outputPath, O outputObject) throws IOException { + validateFilePath(outputPath); + validateObject(outputObject); + + this.writeToFile(outputPath.toFile(), outputObject); + } + + /** + * Translates the object and then writes the translated object to the file + * referenced by the Path + * + * @param the type of the object to write + * @param outputPath the path of the file to write to + * @param outputObject the object to write + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain ResourceError#DIRECTORY_PATH_IS_FILE} + * if path points to a file that doesn't exist and the + * parent path points to a file
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ * @throws IOException if there is an issue writing the file + */ + public final void translateAndWrite(Path outputPath, O outputObject) throws IOException { + validateFilePath(outputPath); + + this.writeToFile(outputPath.toFile(), this.translateObject(outputObject)); + } + + /** + * Translates the object using the given classRef and then writes the translated + * object to the file referenced by the Path + * + * @param the type of the object to write + * @param outputPath the path of the file to write to + * @param outputObject the object to write + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain ResourceError#DIRECTORY_PATH_IS_FILE} + * if path points to a file that doesn't exist and the + * parent path points to a file
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * passed in classRef is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ * @throws IOException if there is an issue writing the file + */ + public final void translateAndWrite(Path outputPath, O outputObject, Class outputClassRef) + throws IOException { + validateFilePath(outputPath); + + this.writeToFile(outputPath.toFile(), this.translateObjectAsClassSafe(outputObject, outputClassRef)); + } + + /** + * Reads the given path into the provided class type + * + * @param the input type + * @param inputPath the path of the file to read + * @param inputClassRef the class to read the file as + * @return the resulting object from reading the file as the class + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain ResourceError#UNKNOWN_FILE} + * if path points to a file that doesn't exist
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} + * if the passed in classRef is null
  • + *
+ * @throws IOException if there is an issue reading the file + */ + public final I read(Path inputPath, Class inputClassRef) throws IOException { + validateFile(inputPath); + validateClass(inputClassRef); + + return this.readFile(inputPath.toFile(), inputClassRef); + } + + /** + * Reads the given path into the provided class type and then translates it to + * the corresponding app type associated with the input type + * + * @param the translated type + * @param the input type + * @param inputPath the path of the file to read + * @param inputClassRef the class to read the file as + * @return the resulting translated read in object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain ResourceError#UNKNOWN_FILE} + * if path points to a file that doesn't exist
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} + * if the passed in classRef is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ * + * @throws IOException if there is an issue reading the file + */ + public final T readAndTranslate(Path inputPath, Class inputClassRef) throws IOException { + validateFile(inputPath); + validateClass(inputClassRef); + + I readObj = this.readFile(inputPath.toFile(), inputClassRef); + + return this.translateObject(readObj); + } + + /** + * Given an object, uses the class of the object to obtain the translationSpec + * and then calls {@link TranslationSpec#translate(Object)} to translate the + * object. + *

+ * This conversion method will be used approximately 90% of the time. + *

+ * + * @param the translated type + * @param object the object to translate + * @return the translated object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ */ + public final T translateObject(Object object) { + validateObject(object); + return getTranslationSpecForClass(object.getClass()).translate(object); + } + + /** + * Given an object, uses the given classRef to obtain the translationSpec and + * then calls {@link TranslationSpec#translate(Object)}. + *

+ * This method call is safe in the sense that the type parameters ensure that + * the passed in object is actually a child of the passed in classRef type. + *

+ *

+ * This conversion method will be used approximately 7% of the time. + *

+ * + * @param the translated type + * @param the type of the object + * @param the type to translate the object as + * @param object the object to translate + * @param translateAsClassRef the classRef of the type to translate the object + * as + * @return the translated object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * passed in classRef is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ */ + public final T translateObjectAsClassSafe(O object, Class translateAsClassRef) { + validateObject(object); + + return getTranslationSpecForClass(translateAsClassRef).translate(object); + } + + /** + * Given an object, uses the given classRef to obtain the translationSpec and + * then calls {@link TranslationSpec#translate(Object)} + *

+ * There is no type safety with this method unlike the + * {@link TaskitEngine#translateObjectAsClassSafe(Object, Class)} method. + * Therefore it is on the caller of this method to ensure that the given object + * can be translated using the given classRef. + *

+ * A conventional use case for this would be when you want to wrap an object + * into another object type where there is no correlation between the wrapping + * object and the object being wrapped. + *

+ *

+ * this conversion method will be used approx ~3% of the time + *

+ * + * @param the translated type + * @param the type of the object + * @param the type to translate the object as + * @param object the object to translate + * @param translateAsClassRef the classRef of the type to translate the object + * @return the translated object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * passed in classRef is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ */ + public final T translateObjectAsClassUnsafe(O object, Class translateAsClassRef) { + validateObject(object); + + return getTranslationSpecForClass(translateAsClassRef).translate(object); + } + + /** + * Package access for testing. + * + * @param the type of the classRef + * @param classRef the classRef to find a translation spec for + * @return the translation spec for the given classRef, if found + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * passed in classRef is null
  • + *
  • + * {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec for the given class was + * found
  • + *
+ */ + public final ITranslationSpec getTranslationSpecForClass(Class classRef) { + validateClass(classRef); + + if (this.data.classToTranslationSpecMap.containsKey(classRef)) { + return this.data.classToTranslationSpecMap.get(classRef); + } + + throw new ContractException(TaskitError.UNKNOWN_TRANSLATION_SPEC, classRef.getName()); + } + + /** + * A hash code implementation consistent with equals(). + */ + @Override + public int hashCode() { + return Objects.hash(data, taskitEngineId, isInitialized); + } + + /** + * Two {@link TaskitEngine}s are equal if and only if they have the same engine + * id, contain the same {@link TranslationSpec}s, and have the same + * initialization state. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (!(obj instanceof TaskitEngine)) { + return false; + } + + TaskitEngine other = (TaskitEngine) obj; + + return Objects.equals(taskitEngineId, other.taskitEngineId) && isInitialized == other.isInitialized + && Objects.equals(data, other.data); + } + + protected abstract void writeToFile(File file, O outputObject) throws IOException; + + protected abstract I readFile(File file, Class inputClassRef) throws IOException; + + private void validateObject(Object object) { + if (object == null) { + throw new ContractException(TaskitError.NULL_OBJECT_FOR_TRANSLATION); + } + } + + private void validateClass(Class classRef) { + if (classRef == null) { + throw new ContractException(TaskitError.NULL_CLASS_REF); + } + } + + private void validateFilePath(Path path) { + if (path == null) { + throw new ContractException(TaskitError.NULL_PATH); + } + + ResourceHelper.validateFilePath(path); + } + + private void validateFile(Path path) { + if (path == null) { + throw new ContractException(TaskitError.NULL_PATH); + } + + ResourceHelper.validateFile(path); + } + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineData.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineData.java new file mode 100644 index 0000000..1f74d3a --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineData.java @@ -0,0 +1,344 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.TranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.graph.Graph; +import gov.hhs.aspr.ms.util.graph.GraphDepthEvaluator; +import gov.hhs.aspr.ms.util.graph.Graphs; +import gov.hhs.aspr.ms.util.graph.MutableGraph; + +/** + * Data class for TaskitEngine. + *

+ * Contains the class to translation spec mapping that resides in the root + * TaskitEngine. + *

+ */ +public final class TaskitEngineData { + // package access for use in TaskitEngine + final Map, ITranslationSpec> classToTranslationSpecMap = new LinkedHashMap<>(); + final Set translationSpecs = new LinkedHashSet<>(); + + private TaskitEngineData(Map, ITranslationSpec> classToTranslationSpecMap, + Set translationSpecs) { + this.classToTranslationSpecMap.putAll(classToTranslationSpecMap); + this.translationSpecs.addAll(translationSpecs); + } + + /** + * Builder class for TaskitEngineData + */ + public static class Builder { + private Map, ITranslationSpec> classToTranslationSpecMap = new LinkedHashMap<>(); + private Set translationSpecs = new LinkedHashSet<>(); + + private List translators = new ArrayList<>(); + + private Builder() { + } + + private void validateTranslationSpec(ITranslationSpec translationSpec) { + if (translationSpec == null) { + throw new ContractException(TaskitError.NULL_TRANSLATION_SPEC); + } + + if (translationSpec.getTranslationSpecClassMapping() == null) { + throw new ContractException(TaskitError.NULL_TRANSLATION_SPEC_CLASS_MAP); + } + + if (translationSpec.getTranslationSpecClassMapping().isEmpty()) { + throw new ContractException(TaskitError.EMPTY_TRANSLATION_SPEC_CLASS_MAP); + } + + if (this.translationSpecs.contains(translationSpec)) { + throw new ContractException(TaskitError.DUPLICATE_TRANSLATION_SPEC); + } + } + + private void validateTranslatorNotNull(Translator translator) { + if (translator == null) { + throw new ContractException(TaskitError.NULL_TRANSLATOR); + } + } + + private void validateTranslationSpecsNotEmpty() { + if (this.translationSpecs.isEmpty()) { + throw new ContractException(TaskitError.NO_TRANSLATION_SPECS); + } + } + + /** + * Builder for the TaskitEngineData + * + * @throws ContractException + *
    + *
  • {@link TaskitError#UNINITIALIZED_TRANSLATORS} + * if translators were added to the engine but their + * initialized flag was still set to false
  • + *
  • {@link TaskitError#DUPLICATE_TRANSLATOR} if a + * duplicate translator is found
  • + *
  • {@link TaskitError#MISSING_TRANSLATOR} if an + * added translator has a unmet dependency
  • + *
  • {@link TaskitError#CIRCULAR_TRANSLATOR_DEPENDENCIES} + * if the added translators have a circular dependency + * graph
  • + *
  • {@link TaskitError#NO_TRANSLATION_SPECS} if no + * translation specs were added to the engine
  • + *
+ */ + public TaskitEngineData build() { + // validate the translators that were added + // they should have an acyclic dependency tree and also all be initialized + if (!this.translators.isEmpty()) { + checkTranslatorGraph(true); + this.translators.clear(); + } + + // There should be at least 1 translation spec added + validateTranslationSpecsNotEmpty(); + + return new TaskitEngineData(classToTranslationSpecMap, translationSpecs); + } + + /** + * Adds the given {@link TranslationSpec} to the TaskitEngine + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TRANSLATION_SPEC} + * if the given translationSpec is null
  • + *
  • {@linkplain TaskitError#NULL_TRANSLATION_SPEC_CLASS_MAP} + * if the given translationSpec's class map is + * null
  • + *
  • {@linkplain TaskitError#EMPTY_TRANSLATION_SPEC_CLASS_MAP} + * if the given translationSpec's class map is + * empty
  • + *
  • {@linkplain TaskitError#DUPLICATE_TRANSLATION_SPEC} + * if the given translationSpec is already known
  • + *
+ */ + public Builder addTranslationSpec(ITranslationSpec translationSpec) { + validateTranslationSpec(translationSpec); + + this.classToTranslationSpecMap.putAll(translationSpec.getTranslationSpecClassMapping()); + + this.translationSpecs.add(translationSpec); + + return this; + } + + /** + * Adds the translator to the TaskitEngineData + *

+ * It is expected that the added translator will be initialized externally + * before calling {@link TaskitEngineData.Builder#build()}. + *

+ * If not, the build method will throw an exception. + * + * @throws ContractException + *

    + *
  • {@linkplain TaskitError#NULL_TRANSLATOR} if + * translator is null
  • + *
+ */ + public Builder addTranslator(Translator translator) { + validateTranslatorNotNull(translator); + + this.translators.add(translator); + + return this; + } + + /* + * Goes through the list of translators and orders them based on their + * dependencies package access for testing + */ + void checkTranslatorGraph(boolean checkInit) { + MutableGraph mutableGraph = new MutableGraph<>(); + Map translatorMap = new LinkedHashMap<>(); + /* + * Add the nodes to the graph, check for duplicate ids, build the mapping from + * plugin id back to plugin + */ + this.addNodes(mutableGraph, translatorMap, checkInit); + + // Add the edges to the graph + this.addEdges(mutableGraph); + + /* + * Check for missing plugins from the plugin dependencies that were collected + * from the known plugins. + */ + checkForMissingTranslators(mutableGraph, translatorMap); + + /* + * Determine whether the graph is acyclic and generate a graph depth evaluator + * for the graph so that we can determine the order of initialization. + */ + checkForCyclicGraph(mutableGraph); + + } + + private void addNodes(MutableGraph mutableGraph, + Map translatorMap, boolean checkInit) { + TranslatorId focalTranslatorId = null; + for (Translator translator : this.translators) { + if (checkInit && !translator.isInitialized()) { + throw new ContractException(TaskitError.UNINITIALIZED_TRANSLATORS); + } + focalTranslatorId = translator.getTranslatorId(); + translatorMap.put(focalTranslatorId, translator); + // ensure that there are no duplicate plugins + if (mutableGraph.containsNode(focalTranslatorId)) { + throw new ContractException(TaskitError.DUPLICATE_TRANSLATOR); + } + mutableGraph.addNode(focalTranslatorId); + focalTranslatorId = null; + } + } + + private void addEdges(MutableGraph mutableGraph) { + TranslatorId focalTranslatorId = null; + for (Translator translator : this.translators) { + focalTranslatorId = translator.getTranslatorId(); + for (TranslatorId translatorId : translator.getTranslatorDependencies()) { + mutableGraph.addEdge(new Object(), focalTranslatorId, translatorId); + } + focalTranslatorId = null; + } + } + + private void checkForMissingTranslators(MutableGraph mutableGraph, + Map translatorMap) { + for (TranslatorId translatorId : mutableGraph.getNodes()) { + if (!translatorMap.containsKey(translatorId)) { + List inboundEdges = mutableGraph.getInboundEdges(translatorId); + StringBuilder sb = new StringBuilder(); + sb.append("cannot locate instance of "); + sb.append(translatorId); + sb.append(" needed for "); + boolean first = true; + for (Object edge : inboundEdges) { + if (first) { + first = false; + } else { + sb.append(", "); + } + TranslatorId dependentTranslatorId = mutableGraph.getOriginNode(edge); + sb.append(dependentTranslatorId); + } + throw new ContractException(TaskitError.MISSING_TRANSLATOR, sb.toString()); + } + } + } + + private void checkForCyclicGraph(MutableGraph mutableGraph) { + Optional> optional = GraphDepthEvaluator + .getGraphDepthEvaluator(mutableGraph.toGraph()); + + if (!optional.isPresent()) { + /* + * Explain in detail why there is a circular dependency + */ + + Graph g = mutableGraph.toGraph(); + g = Graphs.getSourceSinkReducedGraph(g); + g = Graphs.getEdgeReducedGraph(g); + g = Graphs.getSourceSinkReducedGraph(g); + + List> cutGraphs = Graphs.cutGraph(g); + StringBuilder sb = new StringBuilder(); + String lineSeparator = System.getProperty("line.separator"); + sb.append(lineSeparator); + boolean firstCutGraph = true; + + for (Graph cutGraph : cutGraphs) { + if (firstCutGraph) { + firstCutGraph = false; + } else { + sb.append(lineSeparator); + } + sb.append("Dependency group: "); + sb.append(lineSeparator); + Set nodes = cutGraph.getNodes().stream() + .collect(Collectors.toCollection(LinkedHashSet::new)); + + for (TranslatorId node : nodes) { + sb.append("\t"); + sb.append(node); + sb.append(" requires:"); + sb.append(lineSeparator); + for (Object edge : cutGraph.getInboundEdges(node)) { + TranslatorId dependencyNode = cutGraph.getOriginNode(edge); + sb.append("\t"); + sb.append("\t"); + sb.append(dependencyNode); + sb.append(lineSeparator); + } + } + } + throw new ContractException(TaskitError.CIRCULAR_TRANSLATOR_DEPENDENCIES, sb.toString()); + } + } + } + + /** + * @return a new builder for a TaskitEngine + */ + public static Builder builder() { + return new Builder(); + } + + @Override + public int hashCode() { + /* + * Note that we do not include the classToSpec map as part of the hash code + * contract, as there is never a case where it would differ from the + * translationSpec set, since both data structures get populated in the same + * addTranslationSpec() method. The data structure that matters is the list of + * translation specs, not the mapping, which only exists as a convenience map + * for translation purposes + */ + return Objects.hash(translationSpecs); + } + + @Override + public boolean equals(Object obj) { + /* + * Note that we do not include the classToSpec map as part of the equals + * contract, as there is never a case where it would differ from the + * translationSpec set, since both data structures get populated in the same + * addTranslationSpec() method. The data structure that matters is the list of + * translation specs, not the mapping, which only exists as a convenience map + * for translation purposes + */ + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (!(obj instanceof TaskitEngineData)) { + return false; + } + + TaskitEngineData other = (TaskitEngineData) obj; + + return Objects.equals(translationSpecs, other.translationSpecs); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineId.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineId.java new file mode 100644 index 0000000..9dace1e --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineId.java @@ -0,0 +1,8 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +/** + * Used as an identifier for Taskit engines, + */ +public interface TaskitEngineId { + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineManager.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineManager.java new file mode 100644 index 0000000..a5037db --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitEngineManager.java @@ -0,0 +1,441 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import java.nio.file.Path; +import java.util.LinkedHashMap; +import java.util.Map; + +import gov.hhs.aspr.ms.taskit.core.translation.TranslationSpec; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceError; + +/** + * The TaskitEngineManager allows {@link TaskitEngine}s to be added to it, and + * acts as a wrapper around the TaskitEngine read/write/translate methods, using + * the {@link TaskitEngineId} to select which engine to use for the given + * operation + */ +public final class TaskitEngineManager { + private final Data data; + + private TaskitEngineManager(Data data) { + this.data = data; + } + + private final static class Data { + private final Map taskitEngineIdToEngineMap = new LinkedHashMap<>(); + + Data() { + } + } + + /** + * Builder for the TaskitEngineManager + */ + public final static class Builder { + Data data; + + private Builder(Data data) { + this.data = data; + } + + private void validateTaskitEngine(TaskitEngine taskitEngine) { + if (taskitEngine == null) { + throw new ContractException(TaskitError.NULL_TASKIT_ENGINE); + } + + if (!taskitEngine.isInitialized()) { + throw new ContractException(TaskitError.UNINITIALIZED_TASKIT_ENGINE); + } + } + + private void validateTaskitEngineAdded() { + if (this.data.taskitEngineIdToEngineMap.isEmpty()) { + throw new ContractException(TaskitError.NO_TASKIT_ENGINES); + } + } + + /** + * Builds the TaskitEngineManager. + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NO_TASKIT_ENGINES} if + * no TaskitEngines were added
  • + *
+ */ + public TaskitEngineManager build() { + // at least 1 engine must be added + validateTaskitEngineAdded(); + + return new TaskitEngineManager(this.data); + } + + /** + * Adds a {@link TaskitEngine} to this TaskitEngineManager + * + * @param taskitEngine the Taskit engine to add + * @return the builder instance + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
  • {@linkplain TaskitError#UNINITIALIZED_TASKIT_ENGINE} + * if the Taskit engine was not initialized prior to + * adding it to the manager
  • + *
+ */ + public Builder addTaskitEngine(TaskitEngine taskitEngine) { + validateTaskitEngine(taskitEngine); + + this.data.taskitEngineIdToEngineMap.put(taskitEngine.getTaskitEngineId(), taskitEngine); + + return this; + } + } + + /** + * Returns a new instance of TaskitEngineManager Builder + */ + public static Builder builder() { + return new Builder(new Data()); + } + + private void validateTaskitEngine(TaskitEngine taskitEngine) { + if (taskitEngine == null) { + throw new ContractException(TaskitError.NULL_TASKIT_ENGINE); + } + } + + private void validateTaskitEngineId(TaskitEngineId taskitEngineId) { + if (taskitEngineId == null) { + throw new ContractException(TaskitError.NULL_TASKIT_ENGINE_ID); + } + } + + private TaskitEngine getTaskitEngine(TaskitEngineId taskitEngineId) { + validateTaskitEngineId(taskitEngineId); + + TaskitEngine taskitEngine = this.data.taskitEngineIdToEngineMap.get(taskitEngineId); + + validateTaskitEngine(taskitEngine); + + return taskitEngine; + } + + /** + * Using the given {@link TaskitEngineId}'s associated {@link TaskitEngine}, + * reads the given file into the provided class type + * + * @param the input type + * @param inputPath the path of the file to read + * @param inputClassRef the to read the file as + * @param taskitEngineId the taskitEngineId to use to read the file + * @return the resulting object from reading the file as the class + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * classRef is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
+ * @throws RuntimeException if the reading of the file encounters an + * IOException + */ + public I read(Path inputPath, Class inputClassRef, TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = getTaskitEngine(taskitEngineId); + + try { + return taskitEngine.read(inputPath, inputClassRef); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Using the given {@link TaskitEngineId}'s associated {@link TaskitEngine}, + * reads the given file into the provided class type and then translates it to + * the corresponding type associated with the input type. + * + * @param the input type + * @param the translated type + * @param inputPath the path of the file to read + * @param inputClassRef the to read the file as + * @param taskitEngineId the taskitEngineId to use to read the file + * @return the resulting object from reading the file as the class + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * classRef is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
+ * @throws RuntimeException if the reading of the file encounters an + * IOException + */ + public T readAndTranslate(Path inputPath, Class inputClassRef, TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = getTaskitEngine(taskitEngineId); + + try { + return taskitEngine.readAndTranslate(inputPath, inputClassRef); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Using the given {@link TaskitEngineId}'s associated {@link TaskitEngine}, + * writes the object to the file referenced by the Path. + * + * @param the type of the object to write + * @param outputPath the path of the file to write to + * @param outputObject the object to write + * @param taskitEngineId the taskitEngineId to use to write the object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the object is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
+ * @throws RuntimeException if the writing of the file encounters an + * IOException + */ + public void write(Path outputPath, O outputObject, TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = this.getTaskitEngine(taskitEngineId); + + try { + taskitEngine.write(outputPath, outputObject); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Using the given {@link TaskitEngineId}'s associated {@link TaskitEngine}, + * translates the object and then writes the translated object to the file + * reference by the Path. + * + * @param the type of the object to write + * @param outputPath the path of the file to write to + * @param outputObject the object to write + * @param taskitEngineId the taskitEngineId to use to write the object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the object is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
+ * @throws RuntimeException if the writing of the file encounters an + * IOException + */ + public void translateAndWrite(Path outputPath, O outputObject, TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = this.getTaskitEngine(taskitEngineId); + + try { + taskitEngine.translateAndWrite(outputPath, outputObject); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Using the given {@link TaskitEngineId}'s associated {@link TaskitEngine}, + * translates the object as the provided class and then writes the translated + * object to the file referenced by the Path. + *

+ * The type params ensure that the object can be written as the provided class. + *

+ * + * @param the type to translate the object as + * @param the type of the object + * @param outputPath the path of the file to write to + * @param outputObject the object to write + * @param outputClassRef the class to translate the object as + * @param taskitEngineId the taskitEngineId to use to write the object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * output classref is null
  • + *
  • {@linkplain TaskitError#NULL_PATH} if the path + * is null
  • + *
  • {@linkplain ResourceError#FILE_PATH_IS_DIRECTORY} + * if the path points to a directory instead of a + * file
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the object is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
+ * @throws RuntimeException if the writing of the file encounters an + * IOException + */ + public void translateAndWrite(Path outputPath, O outputObject, Class outputClassRef, + TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = this.getTaskitEngine(taskitEngineId); + + try { + taskitEngine.translateAndWrite(outputPath, outputObject, outputClassRef); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Given an object, uses the class of the object to obtain the translationSpec + * and then calls {@link TranslationSpec#translate(Object)} to translate the + * object. + *

+ * this conversion method will be used approximately 90% of the time. + *

+ * + * @param the translated type + * @param object the object to translate + * @param taskitEngineId the taskitEngine to use for translate + * @return the translated object + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ */ + public final T translateObject(Object object, TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = getTaskitEngine(taskitEngineId); + + return taskitEngine.translateObject(object); + } + + /** + * Given an object, uses the given classRef to obtain the translationSpec and + * then calls {@link TranslationSpec#translate(Object)}. + *

+ * This method call is safe in the sense that the type parameters ensure that + * the passed in object is actually a child of the passed in classRef type. + *

+ *

+ * This conversion method will be used approximately 7% of the time. + *

+ * + * @param the translated type + * @param the type of the object + * @param the type to translate the object as + * @param object the object to translate + * @param translateAsClassRef the classRef of the type to translate the object + * as + * @param taskitEngineId the taskitEngine to use for translate + * @return the translated object + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * passed in classRef is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ */ + public final T translateObjectAsClassSafe(O object, Class translateAsClassRef, + TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = getTaskitEngine(taskitEngineId); + + return taskitEngine.translateObjectAsClassSafe(object, translateAsClassRef); + } + + /** + * Given an object, uses the given classRef to obtain the translationSpec and + * then calls {@link TranslationSpec#translate(Object)}. + *

+ * There is no type safety with this method unlike the + * {@link TaskitEngine#translateObjectAsClassSafe(Object, Class)} method. + * Therefore it is on the caller of this method to ensure that the given object + * can be translated using the given classRef. + *

+ * A conventional use case for this would be when you want to wrap an object + * into another object type where there is no correlation between the wrapping + * object and the object being wrapped. + *

+ *

+ * This conversion method will be used approximately 3% of the time. + *

+ * + * @param the translated type + * @param the type of the object + * @param the type to translate the object as + * @param object the object to translate + * @param translateAsClassRef the classRef of the type to translate the object + * as + * @param taskitEngineId the taskitEngine to use for translate + * @return the translated object + * + * @throws ContractException + *
    + * + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE_ID} + * if taskitEngineId is null
  • + *
  • {@linkplain TaskitError#NULL_TASKIT_ENGINE} if + * taskitEngine is null
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
  • + *
  • {@linkplain TaskitError#NULL_CLASS_REF} if the + * passed in classRef is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
  • + *
+ */ + public final T translateObjectAsClassUnsafe(O object, Class translateAsClassRef, + TaskitEngineId taskitEngineId) { + TaskitEngine taskitEngine = getTaskitEngine(taskitEngineId); + + return taskitEngine.translateObjectAsClassUnsafe(object, translateAsClassRef); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitError.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitError.java new file mode 100644 index 0000000..a1ffc4a --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/engine/TaskitError.java @@ -0,0 +1,67 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import gov.hhs.aspr.ms.util.errors.ContractError; + +/** + * Errors that describe contract exceptions within Taskit + */ +public enum TaskitError implements ContractError { + + CIRCULAR_TRANSLATOR_DEPENDENCIES("Circular translator dependencies: "), + DUPLICATE_CLASSREF("Duplicate ClassRef"), + DUPLICATE_DEPENDENCY("Duplicate Dependency"), + DUPLICATE_TRANSLATOR("Duplicate Translator"), + DUPLICATE_TRANSLATION_SPEC("Duplicate TranslationSpec"), + DOUBLE_TRANSLATION_SPEC_INIT("Called init more than once on a translation spec"), + EMPTY_TRANSLATION_SPEC_CLASS_MAP( + "The provided translation spec class map was empty. it must contain at least 1 class to translation spec mapping"), + INVALID_INPUT_CLASS("The given input class is not of the expected type."), + INVALID_OUTPUT_CLASS("The given output class is not of the expected type."), + INVALID_PARENT_OUTPUT_CLASS( + "The given output class is not known to be a parent of the given objects class. You need to specify this in the TaskitEngine Builder, otherwise this check will fail."), + INVALID_OUTPUT_PATH( + "The given output file path does not exist. While the file will be created on write, the directory will not."), + INVALID_TASKIT_ENGINE_BUILDER_CLASS_REF( + "The given Taskit Engine Builder classRef does not match the class of the actual Taskit Engine Builder"), + INVALID_TASKIT_ENGINE( + "Init was called on a translationSpec with a TaskitEngine that was not of the expected type."), + MISSING_TRANSLATOR("Missing Translator: "), + NO_TASKIT_ENGINES("There are no TaskitEngines added to this TaskitEngineManager."), + NO_TRANSLATION_SPECS("There are no translation specs added to this TaskitEngine."), + NULL_CLASS_REF("Null Class Ref"), + NULL_DEPENDENCY("Null dependency"), + NULL_INIT_CONSUMER("Null Initializer Consumer"), + NULL_OBJECT_FOR_TRANSLATION("The object to be translated was null"), + NULL_PATH("Null Path"), + NULL_TASKIT_ENGINE("Null Taskit Engine"), + NULL_TASKIT_ENGINE_BUILDER("Null Taskit Engine Builder"), + NULL_TASKIT_ENGINE_ID("Null Taskit Engine Type"), + NULL_TRANSLATION_SPEC("Null TranslationSpec"), + NULL_TRANSLATION_SPEC_CLASS_MAP("The provided translation spec to class map was null"), + NULL_TRANSLATION_SPEC_APP_CLASS("Null TranslationSpec App Class"), + NULL_TRANSLATION_SPEC_INPUT_CLASS("Null TranslationSpec Input Class"), + NULL_TRANSLATOR("Null Translator"), + NULL_TRANSLATOR_ID("Null TranslatorId"), + TRANSLATORS_WERE_FOUND_WHEN_NOT_EXPECTED( + "Translators were added to the Taskit Engine but the normal build method was called. Translators that are added must be"), + UNINITIALIZED_TRANSLATION_SPEC("TranslationSpec not initialized"), + UNINITIALIZED_TRANSLATORS( + "Translators were added to the builder but were not initialized. Make sure to call super.initTranslators() during your custom engine build method"), + UNINITIALIZED_TASKIT_ENGINE("The TaskitEngine was not initialized. Be sure to call taskitEngine.init()"), + UNKNOWN_CLASSREF("No object has been read in with the specified classRef"), + UNKNOWN_OBJECT("Object is not Translatable by this TranslationSpec"), + UNKNOWN_TASKIT_ENGINE_ID("Taskit Engine ID was not set"), + UNKNOWN_TRANSLATION_SPEC("No translation spec was provided for the given class"), + UNSUPPORTED_VERSION("The given version is not supported"); + + private final String description; + + private TaskitError(final String description) { + this.description = description; + } + + @Override + public String getDescription() { + return description; + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestTranslationEngine.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestTranslationEngine.java deleted file mode 100644 index 8fd5373..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestTranslationEngine.java +++ /dev/null @@ -1,147 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport; - -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Optional; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.stream.JsonReader; - -import gov.hhs.aspr.ms.taskit.core.TranslationEngine; -import gov.hhs.aspr.ms.taskit.core.TranslationEngineType; -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; -import gov.hhs.aspr.ms.taskit.core.Translator; - -public class TestTranslationEngine extends TranslationEngine { - private final Data data; - - private TestTranslationEngine(Data data) { - super(data); - this.data = data; - } - - protected static class Data extends TranslationEngine.Data { - protected Gson gson = new Gson(); - - protected Data() { - super(); - this.translationEngineType = TranslationEngineType.CUSTOM; - } - - private void setUnknownEngineType() { - this.translationEngineType = TranslationEngineType.UNKNOWN; - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj); - } - - } - - public static class Builder extends TranslationEngine.Builder { - private TestTranslationEngine.Data data; - - private Builder(TestTranslationEngine.Data data) { - super(data); - this.data = data; - } - - @Override - public TestTranslationEngine build() { - super.initTranslators(); - - TestTranslationEngine translationEngine = new TestTranslationEngine(this.data); - - translationEngine.initTranslationSpecs(); - translationEngine.validateInit(); - return translationEngine; - } - - public TestTranslationEngine buildWithoutSpecInit() { - super.initTranslators(); - return new TestTranslationEngine(this.data); - } - - public TestTranslationEngine buildWithNoTranslatorInit() { - TestTranslationEngine translationEngine = new TestTranslationEngine(this.data); - translationEngine.initTranslationSpecs(); - - return new TestTranslationEngine(this.data); - } - - public TestTranslationEngine buildWithUnknownType() { - this.data.setUnknownEngineType(); - - return new TestTranslationEngine(this.data); - } - - @Override - public Builder addTranslationSpec(TranslationSpec translationSpec) { - _addTranslationSpec(translationSpec); - - return this; - } - - @Override - public Builder addTranslator(Translator translator) { - _addTranslator(translator); - - return this; - } - - @Override - public Builder addParentChildClassRelationship(Class classRef, Class markerInterface) { - _addParentChildClassRelationship(classRef, markerInterface); - - return this; - } - } - - public static Builder builder() { - return new Builder(new Data()); - } - - @Override - public void writeOutput(Path path, M appObject, Optional> superClass) throws IOException { - Object outputObject; - if (superClass.isPresent()) { - outputObject = convertObjectAsSafeClass(appObject, superClass.get()); - } else { - outputObject = convertObject(appObject); - } - - String stringToWrite = this.data.gson.toJson(outputObject); - FileWriter writer = new FileWriter(path.toFile()); - writer.write(stringToWrite); - writer.flush(); - writer.close(); - } - - @Override - public T readInput(Path path, Class inputClassRef) throws IOException { - JsonObject jsonObject = JsonParser.parseReader(new JsonReader(new FileReader(path.toFile()))).getAsJsonObject(); - - return convertObject(this.data.gson.fromJson(jsonObject.toString(), inputClassRef)); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return super.equals(obj); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestTranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestTranslationSpec.java deleted file mode 100644 index 7139c57..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestTranslationSpec.java +++ /dev/null @@ -1,13 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport; - -import gov.hhs.aspr.ms.taskit.core.TranslationEngine; -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; - -public abstract class TestTranslationSpec extends TranslationSpec { - protected TestTranslationEngine translationEngine; - - public void init(TranslationEngine translationEngine) { - super.init(translationEngine); - this.translationEngine = (TestTranslationEngine) translationEngine; - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TranslationSpecSupport.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TranslationSpecSupport.java deleted file mode 100644 index 2217997..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TranslationSpecSupport.java +++ /dev/null @@ -1,69 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport; - -import java.io.File; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; -import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; - -public class TranslationSpecSupport { - - private TranslationSpecSupport() {} - /* - * This method is to ensure that every translationSpec that is supposed to be - * tied to a Translator is defined in its list of translationSpecs. If a - * translationSpec is added and not subsequently added to the list in the - * Translator, then this test will fail and provide the name of the missing - * TranslationSpec - */ - public static Set testGetTranslationSpecs(Class translatorClassRef, - List> translationSpecs) throws ClassNotFoundException { - Set missingTranslationSpecs = new LinkedHashSet<>(); - List> translationSpecClasses = new ArrayList<>(); - - // create a list with the translation spec class names - for (TranslationSpec translationSpec : translationSpecs) { - translationSpecClasses.add(translationSpec.getClass()); - } - - // get the package of the translator class to get its translationSpecs package - // path - String packageName = translatorClassRef.getPackageName() + ".translationSpecs"; - String packagePath = packageName.replaceAll("[.]", "/"); - - ClassLoader classLoader = ClassLoader.getSystemClassLoader(); - - Path path = ResourceHelper.getResourceDir(translatorClassRef) - .getParent() - .resolve("classes") - .resolve(packagePath); - - // the path from above will be referencing the test-classes compile folder. We - // want the classes folder, else it will fail because the test classes for - // translationSpecs are prefixed with AT_ - File[] files = path.toFile().listFiles(); - - // loop over all the files in the directory, for every file that ends in .class, - // construct the full qualified class name. use the classLoader to load the - // class and assert that the provided list of translationSpecs contains that - // class - for (File file : files) { - String className = file.getName(); - if (className.endsWith(".class")) { - // note the substring here is to eliminate the .class suffix of the filename - className = packageName + "." + className.substring(0, className.length() - 6); - Class classRef = classLoader.loadClass(className); - - if(!translationSpecClasses.contains(classRef)) { - missingTranslationSpecs.add(classRef.getSimpleName()); - } - } - } - - return missingTranslationSpecs; - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TranslatorTestSupport.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TranslatorTestSupport.java new file mode 100644 index 0000000..c21cfc3 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/TranslatorTestSupport.java @@ -0,0 +1,95 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport; + +import java.io.File; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +/** + * Class to help test Translators and their internal list of translation specs + */ +public class TranslatorTestSupport { + + private TranslatorTestSupport() { + } + + /** + * This method is used to ensure that every translationSpec that is supposed to + * be + * tied to a Translator is defined in its list of translationSpecs. If a + * translationSpec is added and not subsequently added to the list in the + * Translator, then this test will fail and provide the name of the missing + * TranslationSpec + * + * @param the type of the translator + * @param translatorClassRef the classRef of the translator + * @param translationSpecs the list of translation specs defined in the + * translator + * @return a set containing any missing translationSpecs defined in the + * translation.spec package for which the translator is located + * @throws ClassNotFoundException if the class loader cannot load a class + * + */ + public static Set testGetTranslationSpecs(Class translatorClassRef, + List translationSpecs) throws ClassNotFoundException { + Set missingTranslationSpecs = new LinkedHashSet<>(); + List> translationSpecClasses = new ArrayList<>(); + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + + // get the package of the translator class to get its translationSpecs package + // path + String packageName = translatorClassRef.getPackageName() + ".specs"; + String packagePath = packageName.replaceAll("[.]", "/"); + + // create a list with the translation spec class names + for (ITranslationSpec translationSpec : translationSpecs) { + translationSpecClasses.add(translationSpec.getClass()); + } + + /* + * the path from above will be referencing the test-classes compile folder. We + * want the classes folder, else it will fail because the test classes for + * translationSpecs are prefixed with AT_. + * + * so we get the root folder via ResourceHelper and then resolve the 'classes' + * directory and then the packagePath directory + */ + Path path = ResourceHelper + .getResourceDir(translatorClassRef) + .getParent() + .resolve("classes") + .resolve(packagePath); + + // list the files in the directory + File[] files = path.toFile().listFiles(); + + // filter out any non class files, if they exist (unlikely) + List fileList = Arrays.asList(files) + .stream() + .filter(file -> file.getName().endsWith(".class")) + .toList(); + + // loop over all the files in the directory, for every file + // construct the full qualified class name. use the classLoader to load the + // class and assert that the provided list of translationSpecs contains that + // class + for (File file : fileList) { + String className = file.getName(); + // note the substring here is to eliminate the .class suffix of the filename + className = packageName + "." + className.substring(0, className.length() - 6); + Class classRef = classLoader.loadClass(className); + + if (!translationSpecClasses.contains(classRef)) { + missingTranslationSpecs.add(classRef.getSimpleName()); + } + } + + return missingTranslationSpecs; + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngine.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngine.java new file mode 100644 index 0000000..ffaf32a --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngine.java @@ -0,0 +1,160 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.engine; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +import gov.hhs.aspr.ms.taskit.core.engine.ITaskitEngineBuilder; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineData; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorContext; +import gov.hhs.aspr.ms.util.errors.ContractException; + +/** + * TestTaskit Engine + *

+ * Implementation serves to allow for testing the TaskitEngine and should + * not be used outside of testing. + *

+ * Can be used as a guide for writing the read/write methods on child + * TaskitEngines. + */ +public final class TestTaskitEngine extends TaskitEngine { + private final Gson gson = new Gson(); + + private TestTaskitEngine(TaskitEngineData taskitEngineData) { + super(taskitEngineData, TestTaskitEngineId.TEST_ENGINE_ID); + } + + /** + * Builder for the TestTaskitEngine + *

+ * Because of the nature of the TestTaskitEngine, this builder is effectively + * just a wrapper around {@link TaskitEngineData.Builder}. + *

+ */ + public static class Builder implements ITaskitEngineBuilder { + + private TaskitEngineData.Builder taskitEngineDataBuilder = TaskitEngineData.builder(); + + private Builder() { + } + + /** + * Builds and initializes a TestTaskitEngine + * + * @return A initialized TestTaskitEngine + * @throws ContractException + *
    + *
  • {@link TaskitError#UNINITIALIZED_TRANSLATORS} + * if translators were added to the engine but their + * initialized flag was still set to false
  • + *
  • {@link TaskitError#DUPLICATE_TRANSLATOR} if a + * duplicate translator is found
  • + *
  • {@link TaskitError#MISSING_TRANSLATOR} if an + * added translator has a unmet dependency
  • + *
  • {@link TaskitError#CIRCULAR_TRANSLATOR_DEPENDENCIES} + * if the added translators have a circular dependency + * graph
  • + *
  • {@link TaskitError#NO_TRANSLATION_SPECS} if no + * translation specs were added to the engine
  • + *
+ */ + public TestTaskitEngine build() { + TestTaskitEngine testTaskitEngine = new TestTaskitEngine(this.taskitEngineDataBuilder.build()); + testTaskitEngine.init(); + + return testTaskitEngine; + } + + /* + * package access for testing. Differs from build method by not initializing the + * engine + */ + TestTaskitEngine buildWithoutInit() { + return new TestTaskitEngine(this.taskitEngineDataBuilder.build()); + } + + /** + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TRANSLATION_SPEC} + * if the given translationSpec is null
  • + *
  • {@linkplain TaskitError#NULL_TRANSLATION_SPEC_CLASS_MAP} + * if the given translationSpec's class map is + * null
  • + *
  • {@linkplain TaskitError#EMPTY_TRANSLATION_SPEC_CLASS_MAP} + * if the given translationSpec's class map is + * empty
  • + *
  • {@linkplain TaskitError#DUPLICATE_TRANSLATION_SPEC} + * if the given translationSpec is already known
  • + *
+ */ + @Override + public Builder addTranslationSpec(ITranslationSpec translationSpec) { + this.taskitEngineDataBuilder.addTranslationSpec(translationSpec); + + return this; + } + + /** + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TRANSLATOR} if + * translator is null
  • + *
+ */ + @Override + public Builder addTranslator(Translator translator) { + this.taskitEngineDataBuilder.addTranslator(translator); + + translator.initialize(new TranslatorContext(this)); + + return this; + } + } + + /** + * @return a new builder instance for a TestTaskitEngine + */ + public static Builder builder() { + return new Builder(); + } + + @Override + protected void writeToFile(File file, O outputObject) throws IOException { + String stringToWrite = this.gson.toJson(outputObject); + FileWriter fileWriter = new FileWriter(file); + + fileWriter.write(stringToWrite); + fileWriter.flush(); + fileWriter.close(); + } + + @Override + protected I readFile(File file, Class inputClassRef) throws IOException { + JsonObject jsonObject = JsonParser.parseReader(new JsonReader(new FileReader(file))) + .getAsJsonObject(); + + return this.gson.fromJson(jsonObject.toString(), inputClassRef); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return super.equals(obj); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngineId.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngineId.java new file mode 100644 index 0000000..c1ff47b --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngineId.java @@ -0,0 +1,13 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.engine; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineId; + +/** + * Test Engine Id for the TestTaskitEngine. + */ +public final class TestTaskitEngineId implements TaskitEngineId { + public static final TaskitEngineId TEST_ENGINE_ID = new TestTaskitEngineId(); + + private TestTaskitEngineId() { + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppChildObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppChildObject.java new file mode 100644 index 0000000..cf018bb --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppChildObject.java @@ -0,0 +1,12 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +/** + * Test class depicting a class that extends another class, creating a parent + * class -> child class relationship + *

+ * Should NOT be used outside of testing + *

+ */ +public class TestAppChildObject extends TestAppObject { + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppEnum.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppEnum.java new file mode 100644 index 0000000..e8a2f09 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppEnum.java @@ -0,0 +1,12 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +/** + * Test class representing a enum. + *

+ * Should NOT be used outside of testing. + *

+ */ +public enum TestAppEnum { + TEST1, + TEST2 +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppObject.java new file mode 100644 index 0000000..0368b10 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestAppObject.java @@ -0,0 +1,126 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +import java.util.Objects; + +/** + * Test class representing a class with various variables, including a Complex + * class. + *

+ * Should NOT be used outside of testing. + *

+ */ +public class TestAppObject { + private int integer; + private boolean bool; + private String string; + private TestComplexAppObject testComplexAppObject; + private TestAppEnum testAppEnum; + + /** + * @return value of the integer variable + */ + public int getInteger() { + return integer; + } + + /** + * Sets the value of the integer variable. + * + * @param integer the value to set + */ + public void setInteger(int integer) { + this.integer = integer; + } + + /** + * @return value of the bool variable + */ + public boolean isBool() { + return bool; + } + + /** + * Sets the value of the bool variable. + * + * @param bool the value to set + */ + public void setBool(boolean bool) { + this.bool = bool; + } + + /** + * @return the value of the string variable + */ + public String getString() { + return string; + } + + /** + * Sets the value of the string variable. + * + * @param string the value to set + */ + public void setString(String string) { + this.string = string; + } + + /** + * @return the value of the complexAppObject variable + */ + public TestComplexAppObject getTestComplexAppObject() { + return testComplexAppObject; + } + + /** + * Sets the value of the complexAppObject variable. + * + * @param testComplexAppObject the value to set + */ + public void setTestComplexAppObject(TestComplexAppObject testComplexAppObject) { + this.testComplexAppObject = testComplexAppObject; + } + + /** + * @return the value of the enum variable + */ + public TestAppEnum getTestAppEnum() { + return this.testAppEnum; + } + + /** + * Sets the value of the enum variable. + * + * @param testAppEnum the value to set + */ + public void setTestAppEnum(TestAppEnum testAppEnum) { + this.testAppEnum = testAppEnum; + } + + /** + * Hash code implementation consistent with equals() + */ + @Override + public int hashCode() { + return Objects.hash(integer, bool, string, testComplexAppObject); + } + + /** + * Two {@link TestAppObject}s are equal if and only they contain identical + * internal values. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TestAppObject other = (TestAppObject) obj; + return integer == other.integer && bool == other.bool && Objects.equals(string, other.string) + && Objects.equals(testComplexAppObject, other.testComplexAppObject); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestComplexAppObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestComplexAppObject.java new file mode 100644 index 0000000..7603aa2 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestComplexAppObject.java @@ -0,0 +1,93 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +import java.util.Objects; + +/** + * Test class that is similar to the TestAppObject class, except that it is a + * class that is the type of one of the variables of the TestAppObject class. + *

+ * Should NOT be used outside of testing. + *

+ */ +public class TestComplexAppObject { + private String testString; + private double startTime; + private int numEntities; + + /** + * @return the value of the string variable + */ + public String getTestString() { + return testString; + } + + /** + * Sets the value of the string variable. + * + * @param testString the value to set + */ + public void setTestString(String testString) { + this.testString = testString; + } + + /** + * @return the value of the startTime variable + */ + public double getStartTime() { + return startTime; + } + + /** + * Sets the value of the startTime variable. + * + * @param startTime the value to set + */ + public void setStartTime(double startTime) { + this.startTime = startTime; + } + + /** + * @return the value of the numEntities variable + */ + public int getNumEntities() { + return numEntities; + } + + /** + * Sets the value of the numEntities variable. + * + * @param numEntities the value to set + */ + public void setNumEntities(int numEntities) { + this.numEntities = numEntities; + } + + /** + * Hash code implentation consistent with equals(). + */ + @Override + public int hashCode() { + return Objects.hash(testString, startTime, numEntities); + } + + /** + * Two {@link TestComplexAppObject}s are equal if and only if their testStrings, + * startTimes, and numEntities are equal. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TestComplexAppObject other = (TestComplexAppObject) obj; + return Objects.equals(testString, other.testString) + && Double.doubleToLongBits(startTime) == Double.doubleToLongBits(other.startTime) + && numEntities == other.numEntities; + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestComplexInputObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestComplexInputObject.java new file mode 100644 index 0000000..6d0c251 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestComplexInputObject.java @@ -0,0 +1,93 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +import java.util.Objects; + +/** + * Complement class of {@link TestComplexAppObject}. + *

+ * Should NOT be used outside of testing. + *

+ */ +public class TestComplexInputObject { + private String testString; + private double startTime; + private int numEntities; + + /** + * @return the value of the string variable + */ + public String getTestString() { + return testString; + } + + /** + * Sets the value of the string variable. + * + * @param testString the value to set + */ + public void setTestString(String testString) { + this.testString = testString; + } + + /** + * @return the value of the startTime variable + */ + public double getStartTime() { + return startTime; + } + + /** + * Sets the value of the startTime variable. + * + * @param startTime the value to set + */ + public void setStartTime(double startTime) { + this.startTime = startTime; + } + + /** + * @return the value of the numEntities variable + */ + public int getNumEntities() { + return numEntities; + } + + /** + * Sets the value of the numEntities variable. + * + * @param numEntities the value to set + */ + public void setNumEntities(int numEntities) { + this.numEntities = numEntities; + } + + /** + * Hash code implementation consistent with equals(). + */ + @Override + public int hashCode() { + return Objects.hash(testString, startTime, numEntities); + } + + /** + * Two {@link TestComplexInputObject}s are equal if and only if their + * testStrings, startTimes, and numEntities are equal. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TestComplexInputObject other = (TestComplexInputObject) obj; + return Objects.equals(testString, other.testString) + && Double.doubleToLongBits(startTime) == Double.doubleToLongBits(other.startTime) + && numEntities == other.numEntities; + } + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestInputChildObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestInputChildObject.java new file mode 100644 index 0000000..7185b8e --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestInputChildObject.java @@ -0,0 +1,11 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +/** + * Complement class to {@link TestAppChildObject}. + *

+ * Should NOT be used outside of testing. + *

+ */ +public class TestInputChildObject extends TestInputObject { + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestInputObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestInputObject.java new file mode 100644 index 0000000..8a12bc9 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestInputObject.java @@ -0,0 +1,112 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +import java.util.Objects; + +/** + * Complement class to {@link TestAppObject} + *

+ * Note this class does not have an enum variable. + *

+ *

+ * Should NOT be used outside of testing. + *

+ */ +public class TestInputObject { + private int integer; + private boolean bool; + private String string; + private TestComplexInputObject testComplexInputObject; + + /** + * @return value of the integer variable + */ + public int getInteger() { + return integer; + } + + /** + * Sets the value of the integer variable. + * + * @param integer the value to set + */ + public void setInteger(int integer) { + this.integer = integer; + } + + /** + * @return value of the bool variable + */ + public boolean isBool() { + return bool; + } + + /** + * Sets the value of the bool variable. + * + * @param bool the value to set + */ + public void setBool(boolean bool) { + this.bool = bool; + } + + /** + * @return the value of the string variable + */ + public String getString() { + return string; + } + + /** + * Sets the value of the string variable. + * + * @param string the value to set + */ + public void setString(String string) { + this.string = string; + } + + /** + * @return the value of the complexInputObject variable + */ + public TestComplexInputObject getTestComplexInputObject() { + return testComplexInputObject; + } + + /** + * Sets the value of the complexInputObject variable. + * + * @param testComplexInputObject the value to set + */ + public void setTestComplexInputObject(TestComplexInputObject testComplexInputObject) { + this.testComplexInputObject = testComplexInputObject; + } + + /** + * Hash code implementation consistent with equals(). + */ + @Override + public int hashCode() { + return Objects.hash(integer, bool, string, testComplexInputObject); + } + + /** + * Two {@link TestInputObject}s are equal if and only if their integers, bools, + * strings, and testComplexInputObjects are equal. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TestInputObject other = (TestInputObject) obj; + return integer == other.integer && bool == other.bool && Objects.equals(string, other.string) + && Objects.equals(testComplexInputObject, other.testComplexInputObject); + } + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestObjectWrapper.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestObjectWrapper.java new file mode 100644 index 0000000..88d5e33 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/TestObjectWrapper.java @@ -0,0 +1,64 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; + +import java.util.Objects; + +/** + * Test class representing a class that wraps another object in it. + *

+ * Should NOT be used outside of testing. + *

+ */ +public class TestObjectWrapper { + private Object wrappedObject; + + /** + * @return the wrappedObject value + */ + public Object getWrappedObject() { + return wrappedObject; + } + + /** + * Sets the value of the wrappedObject variable. + * + * @param wrappedObject the value to set + * + * @throws RuntimeException if the wrappedObject is equal to this instance or is + * itself an instance of this class. This is to prevent + * circular referencing + */ + public void setWrappedObject(Object wrappedObject) { + if (wrappedObject == this || wrappedObject instanceof TestObjectWrapper) { + throw new RuntimeException("Cant set the wrapped object to an instance of itself"); + } + this.wrappedObject = wrappedObject; + } + + /** + * Hash code implementation consistent with equals(). + */ + @Override + public int hashCode() { + return Objects.hashCode(wrappedObject); + } + + /** + * Two {@link TestObjectWrapper}s are equal if and only if their wrappedObjects + * are equal. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + TestObjectWrapper other = (TestObjectWrapper) obj; + return Objects.equals(wrappedObject, other.wrappedObject); + } + +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexAppObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexAppObject.java deleted file mode 100644 index 989d5de..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexAppObject.java +++ /dev/null @@ -1,56 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject; - -import java.util.Objects; - -public class TestComplexAppObject { - private String testString; - private double startTime; - private int numEntities; - - public String getTestString() { - return testString; - } - - public void setTestString(String testString) { - this.testString = testString; - } - - public double getStartTime() { - return startTime; - } - - public void setStartTime(double startTime) { - this.startTime = startTime; - } - - public int getNumEntities() { - return numEntities; - } - - public void setNumEntities(int numEntities) { - this.numEntities = numEntities; - } - - @Override - public int hashCode() { - return Objects.hash(testString, startTime, numEntities); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TestComplexAppObject other = (TestComplexAppObject) obj; - return Objects.equals(testString, other.testString) - && Double.doubleToLongBits(startTime) == Double.doubleToLongBits(other.startTime) - && numEntities == other.numEntities; - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexObjectTranslator.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexObjectTranslator.java deleted file mode 100644 index cf631bd..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexObjectTranslator.java +++ /dev/null @@ -1,18 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject; - -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs.TestComplexObjectTranslationSpec; - -public class TestComplexObjectTranslator { - private TestComplexObjectTranslator() { - } - - public static Translator getTranslator() { - return Translator.builder().setTranslatorId(TestComplexObjectTranslatorId.TRANSLATOR_ID) - .setInitializer(translatorContext -> { - translatorContext.getTranslationEngineBuilder(TestTranslationEngine.Builder.class) - .addTranslationSpec(new TestComplexObjectTranslationSpec()); - }).build(); - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/input/TestComplexInputObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/input/TestComplexInputObject.java deleted file mode 100644 index 0d46257..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/input/TestComplexInputObject.java +++ /dev/null @@ -1,56 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input; - -import java.util.Objects; - -public class TestComplexInputObject { - private String testString; - private double startTime; - private int numEntities; - - public String getTestString() { - return testString; - } - - public void setTestString(String testString) { - this.testString = testString; - } - - public double getStartTime() { - return startTime; - } - - public void setStartTime(double startTime) { - this.startTime = startTime; - } - - public int getNumEntities() { - return numEntities; - } - - public void setNumEntities(int numEntities) { - this.numEntities = numEntities; - } - - @Override - public int hashCode() { - return Objects.hash(testString, startTime, numEntities); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TestComplexInputObject other = (TestComplexInputObject) obj; - return Objects.equals(testString, other.testString) - && Double.doubleToLongBits(startTime) == Double.doubleToLongBits(other.startTime) - && numEntities == other.numEntities; - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppChildObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppChildObject.java deleted file mode 100644 index 83cba27..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppChildObject.java +++ /dev/null @@ -1,5 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; - -public class TestAppChildObject extends TestAppObject { - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppEnum.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppEnum.java deleted file mode 100644 index 241fbde..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppEnum.java +++ /dev/null @@ -1,6 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; - -public enum TestAppEnum { - TEST1, - TEST2 -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppObject.java deleted file mode 100644 index dc91076..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestAppObject.java +++ /dev/null @@ -1,75 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; - -import java.util.Objects; - -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; - -public class TestAppObject { - private int integer; - private boolean bool; - private String string; - private TestComplexAppObject testComplexAppObject; - private TestAppEnum testAppEnum; - - public int getInteger() { - return integer; - } - - public void setInteger(int integer) { - this.integer = integer; - } - - public boolean isBool() { - return bool; - } - - public void setBool(boolean bool) { - this.bool = bool; - } - - public String getString() { - return string; - } - - public void setString(String string) { - this.string = string; - } - - public TestComplexAppObject getTestComplexAppObject() { - return testComplexAppObject; - } - - public void setTestComplexAppObject(TestComplexAppObject testComplexAppObject) { - this.testComplexAppObject = testComplexAppObject; - } - - public void setTestAppEnum(TestAppEnum testAppEnum) { - this.testAppEnum = testAppEnum; - } - - public TestAppEnum getTestAppEnum() { - return this.testAppEnum; - } - - @Override - public int hashCode() { - return Objects.hash(integer, bool, string, testComplexAppObject); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TestAppObject other = (TestAppObject) obj; - return integer == other.integer && bool == other.bool && Objects.equals(string, other.string) - && Objects.equals(testComplexAppObject, other.testComplexAppObject); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectTranslator.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectTranslator.java deleted file mode 100644 index 683189b..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectTranslator.java +++ /dev/null @@ -1,19 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; - -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexObjectTranslatorId; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; - -public class TestObjectTranslator { - private TestObjectTranslator() { - } - - public static Translator getTranslator() { - return Translator.builder().setTranslatorId(TestObjectTranslatorId.TRANSLATOR_ID) - .addDependency(TestComplexObjectTranslatorId.TRANSLATOR_ID).setInitializer(translatorContext -> { - translatorContext.getTranslationEngineBuilder(TestTranslationEngine.Builder.class) - .addTranslationSpec(new TestObjectTranslationSpec()); - }).build(); - } -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectWrapper.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectWrapper.java deleted file mode 100644 index 228b1ca..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectWrapper.java +++ /dev/null @@ -1,39 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; - -import java.util.Objects; - -public class TestObjectWrapper { - private Object wrappedObject; - - public Object getWrappedObject() { - return wrappedObject; - } - - public void setWrappedObject(Object wrappedObject) { - if (wrappedObject == this || wrappedObject instanceof TestObjectWrapper) { - throw new RuntimeException("Cant set the wrapped object to an instance of itself"); - } - this.wrappedObject = wrappedObject; - } - - @Override - public int hashCode() { - return Objects.hashCode(wrappedObject); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TestObjectWrapper other = (TestObjectWrapper) obj; - return Objects.equals(wrappedObject, other.wrappedObject); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/TestInputChildObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/TestInputChildObject.java deleted file mode 100644 index 2a9b659..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/TestInputChildObject.java +++ /dev/null @@ -1,5 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input; - -public class TestInputChildObject extends TestInputObject { - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/TestInputObject.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/TestInputObject.java deleted file mode 100644 index 158fa35..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/TestInputObject.java +++ /dev/null @@ -1,66 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input; - -import java.util.Objects; - -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; - -public class TestInputObject { - private int integer; - private boolean bool; - private String string; - private TestComplexInputObject testComplexInputObject; - - public int getInteger() { - return integer; - } - - public void setInteger(int integer) { - this.integer = integer; - } - - public boolean isBool() { - return bool; - } - - public void setBool(boolean bool) { - this.bool = bool; - } - - public String getString() { - return string; - } - - public void setString(String string) { - this.string = string; - } - - public TestComplexInputObject getTestComplexInputObject() { - return testComplexInputObject; - } - - public void setTestComplexInputObject(TestComplexInputObject testComplexInputObject) { - this.testComplexInputObject = testComplexInputObject; - } - - @Override - public int hashCode() { - return Objects.hash(integer, bool, string, testComplexInputObject); - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - TestInputObject other = (TestInputObject) obj; - return integer == other.integer && bool == other.bool && Objects.equals(string, other.string) - && Objects.equals(testComplexInputObject, other.testComplexInputObject); - } - -} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/testTextFileForTestCoverage.txt b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/testTextFileForTestCoverage.txt deleted file mode 100644 index 892394f..0000000 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/testTextFileForTestCoverage.txt +++ /dev/null @@ -1 +0,0 @@ -wombat \ No newline at end of file diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/TestTranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/TestTranslationSpec.java new file mode 100644 index 0000000..d3a976a --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/TestTranslationSpec.java @@ -0,0 +1,15 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.translation; + +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.translation.TranslationSpec; + +/** + * Test implementation of {@link TranslationSpec} that specifically uses a + * {@link TestTaskitEngine} + */ +public abstract class TestTranslationSpec extends TranslationSpec { + + protected TestTranslationSpec() { + super(TestTaskitEngine.class); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/TestComplexObjectTranslator.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/TestComplexObjectTranslator.java new file mode 100644 index 0000000..de3a1f5 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/TestComplexObjectTranslator.java @@ -0,0 +1,24 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject; + +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs.TestComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; + +/** + * Test translator for the TestComplexObject + */ +public class TestComplexObjectTranslator { + private TestComplexObjectTranslator() { + } + + /** + * @return the translator for the TestComplexObject + */ + public static Translator getTranslator() { + return Translator.builder().setTranslatorId(TestComplexObjectTranslatorId.TRANSLATOR_ID) + .setInitializer(translatorContext -> { + translatorContext.getTaskitEngineBuilder(TestTaskitEngine.Builder.class) + .addTranslationSpec(new TestComplexObjectTranslationSpec()); + }).build(); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexObjectTranslatorId.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/TestComplexObjectTranslatorId.java similarity index 52% rename from core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexObjectTranslatorId.java rename to core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/TestComplexObjectTranslatorId.java index 7eb5816..196300b 100644 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/TestComplexObjectTranslatorId.java +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/TestComplexObjectTranslatorId.java @@ -1,7 +1,10 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject; -import gov.hhs.aspr.ms.taskit.core.TranslatorId; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; +/** + * Translator Id for the TestComplexObjectTranslator + */ public class TestComplexObjectTranslatorId implements TranslatorId { public final static TranslatorId TRANSLATOR_ID = new TestComplexObjectTranslatorId(); diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/translationSpecs/TestComplexObjectTranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/specs/TestComplexObjectTranslationSpec.java similarity index 65% rename from core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/translationSpecs/TestComplexObjectTranslationSpec.java rename to core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/specs/TestComplexObjectTranslationSpec.java index 909e91d..fb531cf 100644 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/translationSpecs/TestComplexObjectTranslationSpec.java +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/specs/TestComplexObjectTranslationSpec.java @@ -1,14 +1,17 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.TestTranslationSpec; +/** + * Translation specifications for TestComplexObject + */ public class TestComplexObjectTranslationSpec extends TestTranslationSpec { @Override - protected TestComplexAppObject convertInputObject(TestComplexInputObject inputObject) { + protected TestComplexAppObject translateInputObject(TestComplexInputObject inputObject) { TestComplexAppObject testAppObject = new TestComplexAppObject(); testAppObject.setNumEntities(inputObject.getNumEntities()); @@ -19,7 +22,7 @@ protected TestComplexAppObject convertInputObject(TestComplexInputObject inputOb } @Override - protected TestComplexInputObject convertAppObject(TestComplexAppObject appObject) { + protected TestComplexInputObject translateAppObject(TestComplexAppObject appObject) { TestComplexInputObject testInputObject = new TestComplexInputObject(); testInputObject.setNumEntities(appObject.getNumEntities()); diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/TestObjectTranslator.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/TestObjectTranslator.java new file mode 100644 index 0000000..6eeadb7 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/TestObjectTranslator.java @@ -0,0 +1,25 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.object; + +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.TestComplexObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; + +/** + * Translator for the TestObject + */ +public class TestObjectTranslator { + private TestObjectTranslator() { + } + + /** + * @return the Translator for the TestObject + */ + public static Translator getTranslator() { + return Translator.builder().setTranslatorId(TestObjectTranslatorId.TRANSLATOR_ID) + .addDependency(TestComplexObjectTranslatorId.TRANSLATOR_ID).setInitializer(translatorContext -> { + translatorContext.getTaskitEngineBuilder(TestTaskitEngine.Builder.class) + .addTranslationSpec(new TestObjectTranslationSpec()); + }).build(); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectTranslatorId.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/TestObjectTranslatorId.java similarity index 51% rename from core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectTranslatorId.java rename to core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/TestObjectTranslatorId.java index 0891b22..ed2a470 100644 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/TestObjectTranslatorId.java +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/TestObjectTranslatorId.java @@ -1,7 +1,10 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.object; -import gov.hhs.aspr.ms.taskit.core.TranslatorId; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; +/** + * TranslatorId for the TestObjectTranslator + */ public class TestObjectTranslatorId implements TranslatorId { public final static TranslatorId TRANSLATOR_ID = new TestObjectTranslatorId(); diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/TestObjectTranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/specs/TestObjectTranslationSpec.java similarity index 56% rename from core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/TestObjectTranslationSpec.java rename to core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/specs/TestObjectTranslationSpec.java index 52c9fe9..472f8f8 100644 --- a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/TestObjectTranslationSpec.java +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/specs/TestObjectTranslationSpec.java @@ -1,33 +1,36 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.TestTranslationSpec; +/** + * Translation Specification for the TestObject + */ public class TestObjectTranslationSpec extends TestTranslationSpec { @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { + protected TestAppObject translateInputObject(TestInputObject inputObject) { TestAppObject testAppObject = new TestAppObject(); testAppObject.setBool(inputObject.isBool()); testAppObject.setInteger(inputObject.getInteger()); testAppObject.setString(inputObject.getString()); testAppObject - .setTestComplexAppObject(this.translationEngine.convertObject(inputObject.getTestComplexInputObject())); + .setTestComplexAppObject(this.taskitEngine.translateObject(inputObject.getTestComplexInputObject())); return testAppObject; } @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { + protected TestInputObject translateAppObject(TestAppObject appObject) { TestInputObject testInputObject = new TestInputObject(); testInputObject.setBool(appObject.isBool()); testInputObject.setInteger(appObject.getInteger()); testInputObject.setString(appObject.getString()); testInputObject - .setTestComplexInputObject(this.translationEngine.convertObject(appObject.getTestComplexAppObject())); + .setTestComplexInputObject(this.taskitEngine.translateObject(appObject.getTestComplexAppObject())); return testInputObject; } diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/ITranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/ITranslationSpec.java new file mode 100644 index 0000000..455b4b1 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/ITranslationSpec.java @@ -0,0 +1,39 @@ +package gov.hhs.aspr.ms.taskit.core.translation; + +import java.util.Map; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; + +/** + * Interface for TranslationSpecifications (TranslationSpecs) + */ +public interface ITranslationSpec { + + /** + * Initializes the translation spec with the given taskitEngine. + * + * @param taskitEngine the taskitEngine the translationSpec should be + * initialized with + */ + public void init(TaskitEngine taskitEngine); + + /** + * Given an object, translates it if the translationSpec knows how to translate + * it + * + * @param the translated type + * @param object the object to translate + * @return the translated object + */ + public T translate(Object object); + + /** + * @return the initialized flag of this translation spec + */ + public boolean isInitialized(); + + /** + * @return a class to TranslationSpec mapping for use in a {@link TaskitEngine} + */ + public Map, ITranslationSpec> getTranslationSpecClassMapping(); +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslationSpec.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslationSpec.java new file mode 100644 index 0000000..f97f8ef --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslationSpec.java @@ -0,0 +1,208 @@ +package gov.hhs.aspr.ms.taskit.core.translation; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.util.errors.ContractException; + +/** + * Core TranslationSpec that must be extended by each translationSpec + * implementor. + *

+ * The implementing spec must define the type of the TaskitEngine it intends to + * use. + *

+ */ +public abstract class TranslationSpec implements ITranslationSpec { + private boolean initialized = false; + protected E taskitEngine; + private final Class taskitEngineClass; + + protected TranslationSpec(Class taskitEngineClass) { + this.taskitEngineClass = taskitEngineClass; + } + + /** + * @throws ContractException + *
    + *
  • {@link TaskitError#DOUBLE_TRANSLATION_SPEC_INIT} + * if init on this translation spec has been called + * more than once
  • + *
  • {@link TaskitError#INVALID_TASKIT_ENGINE} if + * the given taskitEngine is of a different type than + * the one provided in the type parameter.
  • + *
+ */ + @Override + public final void init(TaskitEngine taskitEngine) { + if (this.initialized) { + throw new ContractException(TaskitError.DOUBLE_TRANSLATION_SPEC_INIT); + } + // make sure assignable from E + if (!(this.taskitEngineClass.isAssignableFrom(taskitEngine.getClass()))) { + throw new ContractException(TaskitError.INVALID_TASKIT_ENGINE, + "given:" + taskitEngine.getClass().getName() + " but expected " + this.taskitEngineClass.getName()); + } + + this.taskitEngine = this.taskitEngineClass.cast(taskitEngine); + this.initialized = true; + } + + @Override + public final boolean isInitialized() { + return this.initialized; + } + + /** + * Given an object, translates it if the translationSpec knows how to translate + * it + *

+ * It first checks if the object class is exactly equal to either the App or + * Input Class. + *

+ *

+ * It then checks if the the object class is assignable from either the App or + * Input Class. + *

+ *

+ * After the above checks, calls the appropriate method. + *

+ *

+ * If the object is cannot be translated by this spec, a contract exception is + * thrown. + *

+ * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#UNINITIALIZED_TRANSLATION_SPEC} + * if this method was called before initialization. + *

    + * Note that under normal circumstances, this should + * never happen + *

    + *
  • + *
  • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the given object is null
  • + *
  • {@linkplain TaskitError#UNKNOWN_OBJECT} if the + * given object cannot be translated by this + * translation spec
  • + *
+ */ + @SuppressWarnings("unchecked") + @Override + public T translate(Object object) { + if (!this.initialized) { + throw new ContractException(TaskitError.UNINITIALIZED_TRANSLATION_SPEC); + } + + if (object == null) { + throw new ContractException(TaskitError.NULL_OBJECT_FOR_TRANSLATION); + } + + Class objectClass = object.getClass(); + + boolean isAppObject = this.getAppObjectClass() == objectClass; + boolean isInObject = this.getInputObjectClass() == objectClass; + + boolean isAssignAppObject = this.getAppObjectClass().isAssignableFrom(objectClass); + boolean isAssignInObject = this.getInputObjectClass().isAssignableFrom(objectClass); + + boolean shouldTranslateAsApp = isAppObject || (isAssignAppObject && !isAssignInObject); + boolean shouldTranslateAsIn = isInObject || (isAssignInObject && !isAssignAppObject); + + if (shouldTranslateAsApp) { + return (T) this.translateAppObject((A) object); + } + + if (shouldTranslateAsIn) { + return (T) this.translateInputObject((I) object); + } + + throw new ContractException(TaskitError.UNKNOWN_OBJECT, + "Object is not a " + this.getAppObjectClass().getName() + " and it is not a " + + this.getInputObjectClass().getName() + ". Given object is of type: " + objectClass.getName()); + + } + + /** + * Hash code implementation consistent with equals(); + */ + @Override + public int hashCode() { + return Objects.hash(initialized, getAppObjectClass(), getInputObjectClass()); + } + + /** + * Two {@link TranslationSpec}s are equal if and only if they translate + * identical app and input types and have identical initialization states. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (!(obj instanceof TranslationSpec)) { + return false; + } + + @SuppressWarnings("rawtypes") + TranslationSpec other = (TranslationSpec) obj; + + // if different app class, not equal + if (getAppObjectClass() != other.getAppObjectClass()) { + return false; + } + + // if different input class, not equal + if (getInputObjectClass() != other.getInputObjectClass()) { + return false; + } + + // if not both initialized, not equal + return initialized == other.initialized; + } + + @Override + public final Map, ITranslationSpec> getTranslationSpecClassMapping() { + final Map, ITranslationSpec> translationSpecClassMap = new LinkedHashMap<>(); + + translationSpecClassMap.put(getAppObjectClass(), this); + translationSpecClassMap.put(getInputObjectClass(), this); + + return translationSpecClassMap; + } + + /** + * Translates the given object to its corresponding app type + * + * @param inputObject the input object to translate + * @return the translated object + */ + protected abstract A translateInputObject(I inputObject); + + /** + * Translates the given object to its corresponding input type + * + * @param appObject the app object to translate + * @return the translated object + */ + protected abstract I translateAppObject(A appObject); + + /** + * @return the class of the app type + */ + public abstract Class getAppObjectClass(); + + /** + * @return the class of the input type + */ + public abstract Class getInputObjectClass(); +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/Translator.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/Translator.java new file mode 100644 index 0000000..eef64b7 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/Translator.java @@ -0,0 +1,239 @@ +package gov.hhs.aspr.ms.taskit.core.translation; + +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.util.errors.ContractException; + +/** + * The Translator class serves as a wrapper around one or more + * {@link TranslationSpec}(s) and assists in adding those translationSpecs to + * the {@link TaskitEngine} + */ +public final class Translator { + private final Data data; + private boolean initialized = false; + + private Translator(Data data) { + this.data = data; + } + + // package access for testing + final static class Data { + private TranslatorId translatorId; + private Consumer initializer; + private final Set dependencies = new LinkedHashSet<>(); + + Data() { + } + + @Override + public int hashCode() { + return Objects.hash(translatorId, dependencies); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (getClass() != obj.getClass()) { + return false; + } + + Data other = (Data) obj; + + return Objects.equals(translatorId, other.translatorId) && Objects.equals(dependencies, other.dependencies); + } + + } + + /** + * Builder class for the Translator. + */ + public final static class Builder { + private Data data; + + private Builder(Data data) { + this.data = data; + } + + private void validate() { + if (this.data.translatorId == null) { + throw new ContractException(TaskitError.NULL_TRANSLATOR_ID); + } + if (this.data.initializer == null) { + throw new ContractException(TaskitError.NULL_INIT_CONSUMER); + } + } + + /** + * Builds the Translator. + * + * @return the built translator + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_TRANSLATOR_ID} if + * the translatorId was not set
  • + *
  • {@linkplain TaskitError#NULL_INIT_CONSUMER} if + * the initConsumer was not set
  • + *
+ */ + public Translator build() { + validate(); + + return new Translator(data); + } + + /** + * Sets the translatorId for this Translator + * + * @param translatorId the translatorId to set + * @return the builder instance + * @throws ContractException {@linkplain TaskitError#NULL_TRANSLATOR_ID} if the + * translatorId is null + */ + public Builder setTranslatorId(TranslatorId translatorId) { + if (translatorId == null) { + throw new ContractException(TaskitError.NULL_TRANSLATOR_ID); + } + + this.data.translatorId = translatorId; + + return this; + } + + /** + * Sets the initialization consumer for this translator + * + * @param initConsumer the consumer to use for initialization + * @return the builder instance + * @throws ContractException {@linkplain TaskitError#NULL_INIT_CONSUMER} if the + * initConsumer is null + */ + public Builder setInitializer(Consumer initConsumer) { + if (initConsumer == null) { + throw new ContractException(TaskitError.NULL_INIT_CONSUMER); + } + + this.data.initializer = initConsumer; + + return this; + } + + /** + * Adds a dependency for this Translator + * + * @param dependency the translatorId of the translator this translator should + * depend on + * @return the builder instance + * + * @throws ContractException + *
    + *
  • {@linkplain TaskitError#NULL_DEPENDENCY} if the + * dependency is null
  • + *
  • {@linkplain TaskitError#DUPLICATE_DEPENDENCY} + * if the dependency has already been added
  • + *
+ */ + public Builder addDependency(TranslatorId dependency) { + if (dependency == null) { + throw new ContractException(TaskitError.NULL_DEPENDENCY); + } + + if (this.data.dependencies.contains(dependency)) { + throw new ContractException(TaskitError.DUPLICATE_DEPENDENCY); + } + + this.data.dependencies.add(dependency); + + return this; + } + } + + /** + * Creates a new Builder for a Translator. + * + * @return a new Builder for a Translator + */ + public static Builder builder() { + return new Builder(new Data()); + } + + /** + * Package access for testing. + */ + Consumer getInitializer() { + return this.data.initializer; + } + + /** + * @return the TranslatorId for this Translator. + */ + public TranslatorId getTranslatorId() { + return this.data.translatorId; + } + + /** + * @return the set of dependencies for this Translator. + */ + public Set getTranslatorDependencies() { + return this.data.dependencies; + } + + /** + * Initializes this translator using its initialization consumer. + * + * @param translatorContext the translator context to pass to the initialization + * consumer + */ + public void initialize(TranslatorContext translatorContext) { + this.data.initializer.accept(translatorContext); + this.initialized = true; + } + + /** + * @return the initialized flag of this translator + */ + public boolean isInitialized() { + return this.initialized; + } + + /** + * Hash code implementation consistent with equals(). + */ + @Override + public int hashCode() { + return Objects.hash(data); + } + + /** + * Two {@link Translator}s are equal if and only if they have the same id and + * dependencies. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Translator other = (Translator) obj; + + return Objects.equals(data, other.data); + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslatorContext.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslatorContext.java new file mode 100644 index 0000000..2719f22 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslatorContext.java @@ -0,0 +1,50 @@ +package gov.hhs.aspr.ms.taskit.core.translation; + +import gov.hhs.aspr.ms.taskit.core.engine.ITaskitEngineBuilder; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.util.errors.ContractException; + +/** + * Context that is used by {@link Translator}s for initialization + *

+ * Note: This class exists because the TaskitEngine instance used by a + * Translator may have different build methods, preventing the associated + * consumer using this context from just being a consumer of a + * ITaskitEngineBuilder + *

+ */ +public final class TranslatorContext { + + private final ITaskitEngineBuilder builder; + + /** + * Constructor for the Translator Context. + * + * @param builder the builder of the TaskitEngine + */ + public TranslatorContext(ITaskitEngineBuilder builder) { + this.builder = builder; + } + + /** + * Gets the Taskit engine builder for this context + *

+ * See the note on this class for the usage of this method. + *

+ * + * @param the type of the TaskitEngine + * @param classRef the classRef of the TaskitEngine type + * @return the taskitEngineBuilder + * @throws ContractException {@linkplain TaskitError#INVALID_TASKIT_ENGINE_BUILDER_CLASS_REF} + * if the given classRef does not match the class + */ + public T getTaskitEngineBuilder(Class classRef) { + if (classRef.isAssignableFrom(this.builder.getClass())) { + return classRef.cast(this.builder); + } + + throw new ContractException(TaskitError.INVALID_TASKIT_ENGINE_BUILDER_CLASS_REF, + "No Taskit Engine Builder was found for the type: " + classRef.getName()); + + } +} diff --git a/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslatorId.java b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslatorId.java new file mode 100644 index 0000000..3ba4f31 --- /dev/null +++ b/core/src/main/java/gov/hhs/aspr/ms/taskit/core/translation/TranslatorId.java @@ -0,0 +1,8 @@ +package gov.hhs.aspr.ms.taskit.core.translation; + +/** + * Identifier for Translators. + */ +public interface TranslatorId { + +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationController.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationController.java deleted file mode 100644 index 45261e0..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationController.java +++ /dev/null @@ -1,613 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.List; -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -import gov.hhs.aspr.ms.util.errors.ContractException; -import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; - -public class AT_TranslationController { - - Path basePath = ResourceHelper.getResourceDir(this.getClass()); - Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); - - @Test - @UnitTestForCoverage - public void testValidateTranslationEngine() { - TranslationController translationController = TranslationController.builder() - .addTranslationEngine(TestTranslationEngine.builder().build()) - .buildWithoutInitAndChecks(); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - translationController.validateTranslationEngines(); - }); - - assertEquals(CoreTranslationError.NO_TRANSLATION_ENGINES, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - for (TranslationEngine translationEngine : translationController.data.translationEngines) { - translationController.translationEngines - .put(translationEngine.getTranslationEngineType(), null); - } - translationController.validateTranslationEngines(); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_ENGINE, contractException.getErrorType()); - - RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { - TestTranslationEngine translationEngine2 = TestTranslationEngine.builder() - .buildWithoutSpecInit(); - - translationController.translationEngines.put(translationEngine2.getTranslationEngineType(), - translationEngine2); - - translationController.validateTranslationEngines(); - }); - - assertEquals("TranslationEngine has been built but has not been initialized.", - runtimeException.getMessage()); - - runtimeException = assertThrows(RuntimeException.class, () -> { - for (TranslationEngine translationEngine : translationController.data.translationEngines) { - translationController.translationEngines.put( - translationEngine.getTranslationEngineType(), - translationEngine); - translationController.translationEngineClassToTypeMap.put(translationEngine.getClass(), - null); - } - translationController.validateTranslationEngines(); - }); - - assertEquals( - "Not all Translation Engines have an associated Class -> Type -> Engine Mapping. Something went very wrong.", - runtimeException.getMessage()); - - runtimeException = assertThrows(RuntimeException.class, () -> { - for (TranslationEngine translationEngine : translationController.data.translationEngines) { - translationController.translationEngines.put( - translationEngine.getTranslationEngineType(), - translationEngine); - } - translationController.validateTranslationEngines(); - }); - - assertEquals( - "Not all Translation Engines have an associated Class -> Type -> Engine Mapping. Something went very wrong.", - runtimeException.getMessage()); - } - - @Test - @UnitTestForCoverage - /* - * purpose of this test is to show that if there isn't a valid TranslationEngine - * class -> Translation Engine Type -> Translation Engine mapping, an exception - * is thrown - */ - public void testValidateTranslationEngines() { - TranslationController translationController = TranslationController.builder() - .buildWithoutInitAndChecks(); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - translationController.validateTranslationEngines(); - }); - - assertEquals(CoreTranslationError.NO_TRANSLATION_ENGINES, contractException.getErrorType()); - - // class to type map not populated - RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { - TranslationController translationController2 = TranslationController.builder() - .addTranslationEngine(TestTranslationEngine.builder().build()) - .buildWithoutInitAndChecks(); - for (TranslationEngine translationEngine : translationController2.data.translationEngines) { - translationController2.translationEngines.put( - translationEngine.getTranslationEngineType(), - translationEngine); - } - translationController2.validateTranslationEngines(); - }); - - assertEquals( - "Not all Translation Engines have an associated Class -> Type -> Engine Mapping. Something went very wrong.", - runtimeException.getMessage()); - - // class to type map not fully mapped - runtimeException = assertThrows(RuntimeException.class, () -> { - TranslationController translationController2 = TranslationController.builder() - .addTranslationEngine(TestTranslationEngine.builder().build()) - .buildWithoutInitAndChecks(); - for (TranslationEngine translationEngine : translationController2.data.translationEngines) { - translationController2.translationEngines.put( - translationEngine.getTranslationEngineType(), - translationEngine); - translationController2.translationEngineClassToTypeMap.put(translationEngine.getClass(), - null); - } - translationController2.validateTranslationEngines(); - }); - - assertEquals( - "Not all Translation Engines have an associated Class -> Type -> Engine Mapping. Something went very wrong.", - runtimeException.getMessage()); - - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "readInput", args = {}) - public void testReadInput() { - String fileName = "readInput-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - TranslationController translationController = TranslationController.builder() - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addTranslationEngine(testTranslationEngine).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - translationController.writeOutput(expectedAppObject, filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - - translationController.readInput(); - - assertEquals(1, translationController.getNumObjects()); - - TestAppObject actualTestAppObject = translationController.getFirstObject(TestAppObject.class); - - assertEquals(expectedAppObject, actualTestAppObject); - - // preconditions - - // invalid file path - RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { - translationController.readInput(filePath.resolve("badPath"), TestInputObject.class, - TestTranslationEngine.builder().build()); - }); - - assertTrue(runtimeException.getCause() instanceof IOException); - } - - @Test - @UnitTestForCoverage - public void testWriteOutput_Engine() { - String fileName = "badFilePath-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - TestTranslationEngine engine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - TranslationController translationController = TranslationController.builder() - .addTranslationEngine(engine) - .build(); - - // preconditions - - // if the filePath is invalid - RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { - translationController.writeOutput(filePath, TestObjectUtil.generateTestAppObject(), - Optional.empty(), - engine); - }); - - assertTrue(runtimeException.getCause() instanceof IOException); - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "writeOutput", args = { Object.class, - Path.class, TranslationEngineType.class }) - public void testWriteOutput() { - String fileName = "writeOutput-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()) - .addParentChildClassRelationship(TestAppChildObject.class, TestAppObject.class) - .build(); - - TranslationController translationController = TranslationController.builder() - .addTranslationEngine(testTranslationEngine).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - translationController.writeOutput(expectedAppObject, filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - - TestAppChildObject testAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); - - translationController.writeOutput(testAppChildObject, filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - // preconditions - // CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION is tested by - // testWriteOutput_Base() - // CoreTranslationError#NULL_PATH is tested by testWriteOutput_Base() - // CoreTranslationError#INVALID_OUTPUT_PATH is tested by testWriteOutput_Base() - // CoreTranslationError#NULL_TRANSLATION_ENGINE is tested by - // testWriteOutput_Base() - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "writeOutput", args = { Object.class, Class.class, - Path.class, TranslationEngineType.class }) - public void testWriteOutput_ParentClass() { - String fileName = "writeOutput_ParentClass-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - TranslationController translationController = TranslationController.builder() - .addTranslationEngine(testTranslationEngine).build(); - - TestAppObject appObject = TestObjectUtil.generateTestAppObject(); - TestAppChildObject expectedAppObject = TestObjectUtil.getChildAppFromApp(appObject); - - translationController.writeOutput(expectedAppObject, TestAppObject.class, filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - - // preconditions - // the given parent classref is null - ContractException contractException = assertThrows(ContractException.class, () -> { - Class badClassRef = null; - translationController.writeOutput(expectedAppObject, badClassRef, filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - // preconditions - // CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION is tested by - // testWriteOutput_Base() - // CoreTranslationError#NULL_PATH is tested by testWriteOutput_Base() - // CoreTranslationError#INVALID_OUTPUT_PATH is tested by testWriteOutput_Base() - // CoreTranslationError#NULL_TRANSLATION_ENGINE is tested by - // testWriteOutput_Base() - } - - @Test - @UnitTestForCoverage - public void testWriteOutput_Base() { - String fileName = "writeOutput_Base-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - TranslationController translationController = TranslationController.builder() - .addTranslationEngine(testTranslationEngine).build(); - - TestAppObject appObject = TestObjectUtil.generateTestAppObject(); - TestAppChildObject expectedAppObject = TestObjectUtil.getChildAppFromApp(appObject); - - // preconditions - // the given object is null - ContractException contractException = assertThrows(ContractException.class, () -> { - translationController.writeOutput(null, Optional.empty(), filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); - - // the path is null - contractException = assertThrows(ContractException.class, () -> { - translationController.writeOutput(expectedAppObject, Optional.empty(), null, - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.NULL_PATH, contractException.getErrorType()); - - // if the path is invalid - contractException = assertThrows(ContractException.class, () -> { - translationController.writeOutput(expectedAppObject, Optional.empty(), - filePath.resolve("badPath").resolve(fileName), - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.INVALID_OUTPUT_PATH, contractException.getErrorType()); - - // if the translation engine is null - contractException = assertThrows(ContractException.class, () -> { - translationController.writeOutput(expectedAppObject, Optional.empty(), - filePath.resolve(fileName), - TranslationEngineType.UNKNOWN); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_ENGINE, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "getFirstObject", args = { Class.class }) - public void testGetFirstObject() throws IOException { - String fileName = "getFirstObject-testOutput.json"; - String fileName2 = "getFirstObject-testOutput2.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - TranslationController translationController = TranslationController.builder() - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addInputFilePath(filePath.resolve(fileName2), TestComplexInputObject.class, - TranslationEngineType.CUSTOM) - .addTranslationEngine(testTranslationEngine).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - TestComplexAppObject expectedComplexAppObject = TestObjectUtil.generateTestComplexAppObject(); - - translationController.writeOutput(expectedAppObject, filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - - translationController.writeOutput(expectedComplexAppObject, filePath.resolve(fileName2), - TranslationEngineType.CUSTOM); - - translationController.readInput(); - - assertEquals(2, translationController.getNumObjects()); - TestAppObject actualTestAppObject = translationController.getFirstObject(TestAppObject.class); - assertEquals(1, translationController.getNumObjects()); - - assertNotNull(actualTestAppObject); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - - translationController.getFirstObject(TestInputObject.class); - }); - - assertEquals(CoreTranslationError.UNKNOWN_CLASSREF, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "getObjects", args = { Class.class }) - public void testGetObjects_OfClass() throws IOException { - String fileName = "GetObjects_OfClass_1-testOutput.json"; - String fileName2 = "GetObjects_OfClass_2-testOutput.json"; - String fileName3 = "GetObjects_OfClass_3-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - ResourceHelper.createFile(filePath, fileName3); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - TranslationController translationController = TranslationController.builder() - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addInputFilePath(filePath.resolve(fileName2), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addInputFilePath(filePath.resolve(fileName3), TestComplexInputObject.class, - TranslationEngineType.CUSTOM) - .addTranslationEngine(testTranslationEngine).build(); - - List expectedObjects = TestObjectUtil.getListOfAppObjects(2); - TestComplexAppObject expectedComplexAppObject = TestObjectUtil.generateTestComplexAppObject(); - - translationController.writeOutput(expectedObjects.get(0), filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - translationController.writeOutput(expectedObjects.get(1), filePath.resolve(fileName2), - TranslationEngineType.CUSTOM); - translationController.writeOutput(expectedComplexAppObject, filePath.resolve(fileName3), - TranslationEngineType.CUSTOM); - - translationController.readInput(); - - assertEquals(3, translationController.getNumObjects()); - - List actualObjects = translationController.getObjects(TestAppObject.class); - assertEquals(1, translationController.getNumObjects()); - - assertEquals(2, actualObjects.size()); - - assertTrue(actualObjects.containsAll(expectedObjects)); - - List actualObjects2 = translationController - .getObjects(TestAppObject.class); - assertTrue(actualObjects2.isEmpty()); - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "getObjects", args = {}) - public void testGetObjects() throws IOException { - String fileName = "GetObjects_1-testOutput.json"; - String fileName2 = "GetObjects_2-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - TranslationController translationController = TranslationController.builder() - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addInputFilePath(filePath.resolve(fileName2), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addTranslationEngine(testTranslationEngine).build(); - - List expectedObjects = TestObjectUtil.getListOfAppObjects(2); - - translationController.writeOutput(expectedObjects.get(0), filePath.resolve(fileName), - TranslationEngineType.CUSTOM); - translationController.writeOutput(expectedObjects.get(1), filePath.resolve(fileName2), - TranslationEngineType.CUSTOM); - - translationController.readInput(); - - assertEquals(2, translationController.getNumObjects()); - - List actualObjects = translationController.getObjects(); - assertEquals(0, translationController.getNumObjects()); - assertEquals(2, actualObjects.size()); - - assertTrue(actualObjects.containsAll(expectedObjects)); - } - - @Test - @UnitTestMethod(target = TranslationController.class, name = "builder", args = {}) - public void testBuilder() { - assertNotNull(TranslationController.builder()); - } - - @Test - @UnitTestMethod(target = TranslationController.Builder.class, name = "build", args = {}) - public void testBuild() { - TranslationController translationController = TranslationController.builder() - .addTranslationEngine(TestTranslationEngine.builder().build()).build(); - - assertNotNull(translationController); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().build(); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_ENGINE, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationController.Builder.class, name = "addInputFilePath", args = { Path.class, - Class.class, TranslationEngineType.class }) - public void testAddInputFilePath() { - String fileName = "addInputFilePath-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - - assertDoesNotThrow(() -> TranslationController.builder() - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addTranslationEngine(TestTranslationEngine.builder().build()).build()); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().addInputFilePath(null, TestInputObject.class, - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.NULL_PATH, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().addInputFilePath(filePath.resolve(fileName), null, - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder() - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM) - .addInputFilePath(filePath.resolve(fileName), TestInputObject.class, - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.DUPLICATE_INPUT_PATH, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().addInputFilePath(filePath.resolve("badPath"), - TestInputObject.class, - TranslationEngineType.CUSTOM); - }); - - assertEquals(CoreTranslationError.INVALID_INPUT_PATH, contractException.getErrorType()); - - } - - @Test - @UnitTestMethod(target = TranslationController.Builder.class, name = "addParentChildClassRelationship", args = { - Class.class, Class.class }) - public void testAddParentChildClassRelationship() { - TranslationController.builder().addParentChildClassRelationship(TestAppObject.class, Object.class); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().addParentChildClassRelationship(null, Object.class); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().addParentChildClassRelationship(TestAppObject.class, null); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder() - .addParentChildClassRelationship(TestAppObject.class, Object.class) - .addParentChildClassRelationship(TestAppObject.class, Object.class); - }); - - assertEquals(CoreTranslationError.DUPLICATE_CLASSREF, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationController.Builder.class, name = "addTranslationEngine", args = { - TranslationEngine.class }) - public void testAddTranslationEngine() { - TestTranslationEngine translationEngine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()) - .addParentChildClassRelationship(TestAppObject.class, Object.class).build(); - - TranslationController.builder().addTranslationEngine(translationEngine).build(); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - TranslationController.builder().addTranslationEngine(null); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_ENGINE, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - TestTranslationEngine translationEngine2 = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()) - .addParentChildClassRelationship(TestAppObject.class, Object.class).build(); - - TranslationController.builder() - .addParentChildClassRelationship(TestAppObject.class, Object.class) - .addTranslationEngine(translationEngine2); - }); - - assertEquals(CoreTranslationError.DUPLICATE_CLASSREF, contractException.getErrorType()); - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationEngine.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationEngine.java deleted file mode 100644 index f7a48e1..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationEngine.java +++ /dev/null @@ -1,486 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexObjectTranslatorId; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs.TestComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslatorId; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectWrapper; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; -import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -import gov.hhs.aspr.ms.util.errors.ContractException; -import gov.hhs.aspr.ms.util.graph.MutableGraph; - -public class AT_TranslationEngine { - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "isInitialized", args = {}) - public void testIsInitialized() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .buildWithoutSpecInit(); - - assertFalse(testTranslationEngine.isInitialized); - - testTranslationEngine.initTranslationSpecs(); - assertTrue(testTranslationEngine.isInitialized()); - } - - @Test - @UnitTestForCoverage - public void testValidateTranslationEngineType() { - // preconditions - // TranslationEngineType is set to UNKNOWN - ContractException contractException = assertThrows(ContractException.class, () -> { - TranslationEngine engine = TestTranslationEngine.builder().buildWithUnknownType(); - - engine.validateInit(); - }); - - assertEquals(CoreTranslationError.UNKNOWN_TRANSLATION_ENGINE_TYPE, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "getTranslationEngineType", args = {}) - public void testGetTranslationEngineType() { - TranslationEngine translationEngine = TestTranslationEngine.builder().build(); - - assertEquals(TranslationEngineType.CUSTOM, translationEngine.getTranslationEngineType()); - - translationEngine = TestTranslationEngine.builder().buildWithUnknownType(); - - assertEquals(TranslationEngineType.UNKNOWN, translationEngine.getTranslationEngineType()); - } - - @Test - @UnitTestForCoverage - public void testTranslationSpecsAreInitialized() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - assertDoesNotThrow(() -> testTranslationEngine.translationSpecsAreInitialized()); - - // preconditions - // one or more Translation Specs are not properly initialized - assertThrows(RuntimeException.class, () -> { - TestTranslationEngine testTranslationEngine2 = TestTranslationEngine.builder() - .addTranslationSpec(new TestObjectTranslationSpec()) - .addTranslationSpec(testComplexObjectTranslationSpec).buildWithoutSpecInit(); - - testTranslationEngine2.translationSpecsAreInitialized(); - }); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "getTranslationSpecs", args = {}) - public void testGetTranslationSpecs() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - Set actualTranslationSpecs = testTranslationEngine.getTranslationSpecs(); - - assertTrue(actualTranslationSpecs.contains(testObjectTranslationSpec)); - assertTrue(actualTranslationSpecs.contains(testComplexObjectTranslationSpec)); - } - - @Test - @UnitTestForCoverage - public void testValidateTranslatorsInitialized() { - - assertDoesNotThrow(() -> { - TestTranslationEngine.builder().addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); - - }); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - TranslationEngine engine = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()).buildWithNoTranslatorInit(); - engine.validateInit(); - }); - assertEquals(CoreTranslationError.UNINITIALIZED_TRANSLATORS, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "convertObject", args = { Object.class }) - public void testConvertObject() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); - - TestInputObject actualInputObject = testTranslationEngine.convertObject(expectedAppObject); - assertEquals(expectedInputObject, actualInputObject); - - TestAppObject actualAppObject = testTranslationEngine.convertObject(expectedInputObject); - assertEquals(expectedAppObject, actualAppObject); - - // preconditions - // the contract exception for CoreTranslationError.UNKNOWN_TRANSLATION_SPEC is - // covered by the test - testGetTranslationSpecForClass - - // the passed in object is null - ContractException contractException = assertThrows(ContractException.class, () -> { - testTranslationEngine.convertObject(null); - }); - - assertEquals(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "convertObjectAsSafeClass", args = { Object.class, - Class.class }) - public void testConvertObjectAsSafeClass() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); - - TestAppChildObject expectedAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); - TestInputChildObject expectedInputChildObject = TestObjectUtil.getChildInputFromInput(expectedInputObject); - - TestInputObject actualInputChildObject = testTranslationEngine.convertObjectAsSafeClass(expectedAppChildObject, - TestAppObject.class); - assertEquals(expectedInputChildObject, TestObjectUtil.getChildInputFromInput(actualInputChildObject)); - - TestAppObject actualAppChildObject = testTranslationEngine.convertObjectAsSafeClass(expectedInputChildObject, - TestInputObject.class); - assertEquals(expectedAppChildObject, TestObjectUtil.getChildAppFromApp(actualAppChildObject)); - - // preconditions - // the contract exception for CoreTranslationError.UNKNOWN_TRANSLATION_SPEC is - // covered by the test - testGetTranslationSpecForClass - - // the passed in object is null - ContractException contractException = assertThrows(ContractException.class, () -> { - testTranslationEngine.convertObjectAsSafeClass(null, Object.class); - }); - - assertEquals(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); - - // the passed in parentClassRef is null - contractException = assertThrows(ContractException.class, () -> { - testTranslationEngine.convertObjectAsSafeClass(expectedAppChildObject, null); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "convertObjectAsUnsafeClass", args = { Object.class, - Class.class }) - public void testConvertObjectAsUnsafeClass() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - // custom Translation Spec to simulate a Spec that might use a class to "wrap" - // another class - TranslationSpec wrapperTranslationSpec = new TranslationSpec() { - - @Override - protected Object convertInputObject(TestObjectWrapper inputObject) { - return inputObject.getWrappedObject(); - } - - @Override - protected TestObjectWrapper convertAppObject(Object appObject) { - TestObjectWrapper objectWrapper = new TestObjectWrapper(); - - objectWrapper.setWrappedObject(appObject); - - return objectWrapper; - } - - @Override - public Class getAppObjectClass() { - return Object.class; - } - - @Override - public Class getInputObjectClass() { - return TestObjectWrapper.class; - } - }; - - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .addTranslationSpec(wrapperTranslationSpec).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - TestObjectWrapper expectedWrapper = new TestObjectWrapper(); - expectedWrapper.setWrappedObject(expectedAppObject); - - TestObjectWrapper actualWrapper = testTranslationEngine.convertObjectAsUnsafeClass(expectedAppObject, - TestObjectWrapper.class); - - assertEquals(expectedWrapper, actualWrapper); - - Object actualAppObject = testTranslationEngine.convertObject(actualWrapper); - - assertEquals(expectedAppObject, actualAppObject); - - // preconditions - // the contract exception for CoreTranslationError.UNKNOWN_TRANSLATION_SPEC is - // covered by the test - testGetTranslationSpecForClass - - // the passed in object is null - ContractException contractException = assertThrows(ContractException.class, () -> { - testTranslationEngine.convertObjectAsUnsafeClass(null, Object.class); - }); - - assertEquals(CoreTranslationError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); - - // the passed in parentClassRef is null - contractException = assertThrows(ContractException.class, () -> { - testTranslationEngine.convertObjectAsUnsafeClass(expectedAppObject, null); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - } - - @Test - @UnitTestForCoverage - public void testGetTranslationSpecForClass() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - assertEquals(testObjectTranslationSpec, testTranslationEngine.getTranslationSpecForClass(TestAppObject.class)); - assertEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestInputObject.class)); - - assertNotEquals(testComplexObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestAppObject.class)); - assertNotEquals(testComplexObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestInputObject.class)); - - assertEquals(testComplexObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestComplexAppObject.class)); - assertEquals(testComplexObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestComplexInputObject.class)); - - assertNotEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestComplexAppObject.class)); - assertNotEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(TestComplexInputObject.class)); - - // preconditions - // no Translation Spec exists for the given class - ContractException contractException = assertThrows(ContractException.class, () -> { - testTranslationEngine.getTranslationSpecForClass(Object.class); - }); - - assertEquals(CoreTranslationError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); - } - - @Test - @UnitTestForCoverage - public void testGetOrderedTranslators() { - - TranslationEngine.Builder translationEngineBuilder = TestTranslationEngine.builder() - .addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestComplexObjectTranslator.getTranslator()); - - List expectedList = new ArrayList<>(); - expectedList.add(TestComplexObjectTranslator.getTranslator()); - expectedList.add(TestObjectTranslator.getTranslator()); - - List actualList = translationEngineBuilder.getOrderedTranslators(); - - assertEquals(expectedList, actualList); - - // preconditions - - // duplicate translator in the graph - - ContractException contractException = assertThrows(ContractException.class, () -> { - MutableGraph mutableGraph = new MutableGraph<>(); - Map translatorMap = new LinkedHashMap<>(); - mutableGraph.addNode(TestObjectTranslatorId.TRANSLATOR_ID); - translationEngineBuilder.addNodes(mutableGraph, translatorMap); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATOR, contractException.getErrorType()); - - // missing translator - contractException = assertThrows(ContractException.class, () -> { - MutableGraph mutableGraph = new MutableGraph<>(); - Map translatorMap = new LinkedHashMap<>(); - - // call normally - translationEngineBuilder.getOrderedTranslators(mutableGraph, translatorMap); - // remove a mapping - translatorMap.remove(TestComplexObjectTranslatorId.TRANSLATOR_ID); - TranslatorId thirdId = new TranslatorId() { - }; - mutableGraph.addNode(thirdId); - mutableGraph.addEdge(new Object(), thirdId, TestComplexObjectTranslatorId.TRANSLATOR_ID); - translationEngineBuilder.checkForMissingTranslators(mutableGraph, translatorMap); - }); - - assertEquals(CoreTranslationError.MISSING_TRANSLATOR, contractException.getErrorType()); - - // cyclic graph - contractException = assertThrows(ContractException.class, () -> { - MutableGraph mutableGraph = new MutableGraph<>(); - Map translatorMap = new LinkedHashMap<>(); - - // call normally - translationEngineBuilder.getOrderedTranslators(mutableGraph, translatorMap); - mutableGraph.addEdge(new Object(), TestComplexObjectTranslatorId.TRANSLATOR_ID, - TestObjectTranslatorId.TRANSLATOR_ID); - TranslatorId thirdId = new TranslatorId() { - }; - TranslatorId fourthId = new TranslatorId() { - }; - mutableGraph.addNode(thirdId); - mutableGraph.addNode(fourthId); - mutableGraph.addEdge(new Object(), thirdId, fourthId); - mutableGraph.addEdge(new Object(), fourthId, thirdId); - translationEngineBuilder.checkForCyclicGraph(mutableGraph); - }); - - assertEquals(CoreTranslationError.CIRCULAR_TRANSLATOR_DEPENDENCIES, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "hashCode", args = {}) - public void testHashCode() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine1 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - TestTranslationEngine testTranslationEngine2 = TestTranslationEngine.builder() - .addTranslationSpec(testComplexObjectTranslationSpec).build(); - - TestTranslationEngine testTranslationEngine3 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).build(); - - TestTranslationEngine testTranslationEngine4 = TestTranslationEngine.builder().build(); - - TestTranslationEngine testTranslationEngine5 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - // exact same, same hash code - assertEquals(testTranslationEngine1.hashCode(), testTranslationEngine1.hashCode()); - - // different translation specs - assertNotEquals(testTranslationEngine1.hashCode(), testTranslationEngine2.hashCode()); - assertNotEquals(testTranslationEngine1.hashCode(), testTranslationEngine3.hashCode()); - assertNotEquals(testTranslationEngine1.hashCode(), testTranslationEngine4.hashCode()); - assertNotEquals(testTranslationEngine2.hashCode(), testTranslationEngine3.hashCode()); - assertNotEquals(testTranslationEngine2.hashCode(), testTranslationEngine4.hashCode()); - assertNotEquals(testTranslationEngine3.hashCode(), testTranslationEngine4.hashCode()); - - // same translation specs - assertEquals(testTranslationEngine1.hashCode(), testTranslationEngine5.hashCode()); - } - - @Test - @UnitTestMethod(target = TranslationEngine.class, name = "equals", args = { Object.class }) - public void testEquals() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine1 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - TestTranslationEngine testTranslationEngine2 = TestTranslationEngine.builder() - .addTranslationSpec(testComplexObjectTranslationSpec).build(); - - TestTranslationEngine testTranslationEngine3 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).build(); - - TestTranslationEngine testTranslationEngine4 = TestTranslationEngine.builder().build(); - - TestTranslationEngine testTranslationEngine5 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(testComplexObjectTranslationSpec) - .build(); - - TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); - TestObjectTranslationSpec testObjectTranslationSpec3 = new TestObjectTranslationSpec(); - - TestTranslationEngine testTranslationEngine6 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec2).buildWithoutSpecInit(); - - TestTranslationEngine testTranslationEngine7 = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec3).buildWithoutSpecInit(); - - // exact same - assertEquals(testTranslationEngine1, testTranslationEngine1); - - assertNotEquals(testTranslationEngine1, null); - - assertNotEquals(testTranslationEngine1, new Object()); - - // different translation specs - assertNotEquals(testTranslationEngine1, testTranslationEngine2); - assertNotEquals(testTranslationEngine1, testTranslationEngine3); - assertNotEquals(testTranslationEngine1, testTranslationEngine4); - assertNotEquals(testTranslationEngine2, testTranslationEngine3); - assertNotEquals(testTranslationEngine2, testTranslationEngine4); - assertNotEquals(testTranslationEngine3, testTranslationEngine4); - - testObjectTranslationSpec2.init(testTranslationEngine1); - testObjectTranslationSpec3.init(testTranslationEngine5); - assertNotEquals(testTranslationEngine6, testTranslationEngine7); - - // init vs not init - assertNotEquals(testTranslationEngine1, testTranslationEngine6); - - // same translation specs - assertEquals(testTranslationEngine1, testTranslationEngine5); - - TranslationEngine.Data data = new TranslationEngine.Data(); - assertEquals(data, data); - assertNotEquals(data, null); - assertNotEquals(data, new Object()); - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationSpec.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationSpec.java deleted file mode 100644 index d208c68..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslationSpec.java +++ /dev/null @@ -1,448 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs.TestComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; -import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -import gov.hhs.aspr.ms.util.errors.ContractException; - -public class AT_TranslationSpec { - - @Test - @UnitTestConstructor(target = TranslationSpec.class, args = {}) - public void testConstructor() { - TranslationSpec translationSpec = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - assertNotNull(translationSpec); - } - - @Test - @UnitTestMethod(target = TranslationSpec.class, name = "init", args = { TranslationEngine.class }) - public void testInit() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).build(); - - testObjectTranslationSpec.init(testTranslationEngine); - - assertTrue(testObjectTranslationSpec.isInitialized()); - - } - - @Test - @UnitTestMethod(target = TranslationSpec.class, name = "isInitialized", args = {}) - public void testIsInitialized() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).build(); - - testObjectTranslationSpec.init(testTranslationEngine); - - assertTrue(testObjectTranslationSpec.isInitialized()); - - assertFalse(new TestObjectTranslationSpec().isInitialized()); - } - - @Test - @UnitTestMethod(target = TranslationSpec.class, name = "convert", args = { Object.class }) - public void testConvert() { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); - - testObjectTranslationSpec.init(testTranslationEngine); - complexObjectTranslationSpec.init(testTranslationEngine); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); - - TestInputObject actualInputObject = testObjectTranslationSpec.convert(expectedAppObject); - assertEquals(expectedInputObject, actualInputObject); - - TestAppObject actualAppObject = testObjectTranslationSpec.convert(expectedInputObject); - assertEquals(expectedAppObject, actualAppObject); - - TestAppChildObject expectedAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); - TestInputChildObject expectedInputChildObject = TestObjectUtil.getChildInputFromInput(expectedInputObject); - - TestInputObject actualInputChildObject = testObjectTranslationSpec.convert(expectedAppChildObject); - assertEquals(expectedInputChildObject, TestObjectUtil.getChildInputFromInput(actualInputChildObject)); - - TestAppObject actualAppChildObject = testObjectTranslationSpec.convert(expectedInputChildObject); - assertEquals(expectedAppChildObject, TestObjectUtil.getChildAppFromApp(actualAppChildObject)); - - // precondition - // TranslationSpec not initialized - ContractException contractException = assertThrows(ContractException.class, () -> { - TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); - testObjectTranslationSpec2.convert(new TestAppObject()); - }); - - assertEquals(CoreTranslationError.UNINITIALIZED_TRANSLATION_SPEC, contractException.getErrorType()); - - // unknown object - contractException = assertThrows(ContractException.class, () -> { - TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); - testObjectTranslationSpec2.init(testTranslationEngine); - testObjectTranslationSpec2.convert(new TestComplexInputObject()); - }); - - assertEquals(CoreTranslationError.UNKNOWN_OBJECT, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = TranslationSpec.class, name = "hashCode", args = {}) - public void testHashCode() { - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder().build(); - // base - TranslationSpec translationSpecA = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - // same input class, different app class - TranslationSpec translationSpecB = new TranslationSpec<>() { - - @Override - protected TestAppChildObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppChildObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppChildObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - // same app class, different input class - TranslationSpec translationSpecC = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputChildObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputChildObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputChildObject.class; - } - - }; - - // different app and different input class - TranslationSpec translationSpecD = new TranslationSpec<>() { - - @Override - protected TestAppChildObject convertInputObject(TestInputChildObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputChildObject convertAppObject(TestAppChildObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppChildObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputChildObject.class; - } - - }; - - // duplicate of the base - TranslationSpec translationSpecE = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - // init the duplicate base - translationSpecE.init(testTranslationEngine); - - // same exact object should be equal - assertEquals(translationSpecA.hashCode(), translationSpecA.hashCode()); - - // different types of objects should not be equal - assertNotEquals(translationSpecA.hashCode(), new Object().hashCode()); - - // different app class should not be equal - assertNotEquals(translationSpecA.hashCode(), translationSpecB.hashCode()); - - // different input class should not be equal - assertNotEquals(translationSpecA.hashCode(), translationSpecC.hashCode()); - - // different input and different app class should not be equal - assertNotEquals(translationSpecA.hashCode(), translationSpecD.hashCode()); - - // if one is initialized and the other is not, they should not be equal - assertNotEquals(translationSpecA.hashCode(), translationSpecE.hashCode()); - - // init base - translationSpecA.init(testTranslationEngine); - - // if all above are equal, then the two specs are equal - assertEquals(translationSpecA.hashCode(), translationSpecE.hashCode()); - } - - @Test - @UnitTestMethod(target = TranslationSpec.class, name = "equals", args = { Object.class }) - public void testEquals() { - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder().build(); - // base - TranslationSpec translationSpecA = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - // same input class, different app class - TranslationSpec translationSpecB = new TranslationSpec<>() { - - @Override - protected TestAppChildObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppChildObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppChildObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - // same app class, different input class - TranslationSpec translationSpecC = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputChildObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputChildObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputChildObject.class; - } - - }; - - // different app and different input class - TranslationSpec translationSpecD = new TranslationSpec<>() { - - @Override - protected TestAppChildObject convertInputObject(TestInputChildObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputChildObject convertAppObject(TestAppChildObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppChildObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputChildObject.class; - } - - }; - - // duplicate of the base - TranslationSpec translationSpecE = new TranslationSpec<>() { - - @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertInputObject'"); - } - - @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { - throw new UnsupportedOperationException("Unimplemented method 'convertAppObject'"); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }; - - // init the duplicate base - translationSpecE.init(testTranslationEngine); - - // same exact object should be equal - assertEquals(translationSpecA, translationSpecA); - - // null object should not be equal - assertNotEquals(translationSpecA, null); - - // different types of objects should not be equal - assertNotEquals(translationSpecA, new Object()); - - // different app class should not be equal - assertNotEquals(translationSpecA, translationSpecB); - - // different input class should not be equal - assertNotEquals(translationSpecA, translationSpecC); - - // different input and different app class should not be equal - assertNotEquals(translationSpecA, translationSpecD); - - // if one is initialized and the other is not, they should not be equal - assertNotEquals(translationSpecA, translationSpecE); - - // init base - translationSpecA.init(testTranslationEngine); - - // if all above are equal, then the two specs are equal - assertEquals(translationSpecA, translationSpecE); - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslatorContext.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslatorContext.java deleted file mode 100644 index 2d70269..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_TranslatorContext.java +++ /dev/null @@ -1,46 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -import gov.hhs.aspr.ms.util.errors.ContractException; - -public class AT_TranslatorContext { - - @Test - @UnitTestConstructor(target = TranslatorContext.class, args = { TranslationEngine.Builder.class }) - public void testConstructor() { - TranslatorContext translatorContext = new TranslatorContext(TestTranslationEngine.builder()); - - assertNotNull(translatorContext); - } - - @Test - @UnitTestMethod(target = TranslatorContext.class, name = "getTranslationEngineBuilder", args = { Class.class }) - public void testGetTranslationEngineBuilder() { - TestTranslationEngine.Builder expectedBuilder = TestTranslationEngine.builder(); - - TranslatorContext translatorContext = new TranslatorContext(expectedBuilder); - - TestTranslationEngine.Builder actualBuilder = translatorContext - .getTranslationEngineBuilder(TestTranslationEngine.Builder.class); - assertTrue(expectedBuilder == actualBuilder); - - // preconditions - - // invalid class ref - ContractException contractException = assertThrows(ContractException.class, () -> { - translatorContext.getTranslationEngineBuilder(TranslationEngine.Builder.class); - }); - - assertEquals(CoreTranslationError.INVALID_TRANSLATION_ENGINE_BUILDER_CLASS_REF, contractException.getErrorType()); - } - -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/TranslationEngineTestHelper.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/TranslationEngineTestHelper.java deleted file mode 100644 index bce8f9e..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/TranslationEngineTestHelper.java +++ /dev/null @@ -1,176 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs.TestComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectWrapper; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; -import gov.hhs.aspr.ms.util.errors.ContractException; - -public final class TranslationEngineTestHelper { - private TranslationEngineTestHelper() { - } - - public static void testAddTranslationSpec(TranslationEngine.Builder builder) { - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TranslationEngine testTranslationEngine = builder.addTranslationSpec(testObjectTranslationSpec) - .addTranslationSpec(testComplexObjectTranslationSpec).build(); - - // show that the translation specs are retrievable by their own app and input - // classes - assertEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(testObjectTranslationSpec.getAppObjectClass())); - assertEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(testObjectTranslationSpec.getInputObjectClass())); - - assertEquals(testComplexObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(testComplexObjectTranslationSpec.getAppObjectClass())); - assertEquals(testComplexObjectTranslationSpec, testTranslationEngine - .getTranslationSpecForClass(testComplexObjectTranslationSpec.getInputObjectClass())); - - builder.clearBuilder(); - // preconditions - // translationSpec is null - ContractException contractException = assertThrows(ContractException.class, () -> { - builder.addTranslationSpec(null); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_SPEC, contractException.getErrorType()); - - builder.clearBuilder(); - // the translation spec getAppClass method returns null - contractException = assertThrows(ContractException.class, () -> { - TranslationSpec wrapperTranslationSpec = new TranslationSpec() { - - @Override - protected Object convertInputObject(TestObjectWrapper inputObject) { - return inputObject.getWrappedObject(); - } - - @Override - protected TestObjectWrapper convertAppObject(Object appObject) { - TestObjectWrapper objectWrapper = new TestObjectWrapper(); - - objectWrapper.setWrappedObject(appObject); - - return objectWrapper; - } - - @Override - public Class getAppObjectClass() { - return null; - } - - @Override - public Class getInputObjectClass() { - return TestObjectWrapper.class; - } - }; - builder.addTranslationSpec(wrapperTranslationSpec); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_SPEC_APP_CLASS, contractException.getErrorType()); - - builder.clearBuilder(); - // the translation spec getInputClass method returns null - contractException = assertThrows(ContractException.class, () -> { - TranslationSpec wrapperTranslationSpec = new TranslationSpec() { - - @Override - protected Object convertInputObject(TestObjectWrapper inputObject) { - return inputObject.getWrappedObject(); - } - - @Override - protected TestObjectWrapper convertAppObject(Object appObject) { - TestObjectWrapper objectWrapper = new TestObjectWrapper(); - - objectWrapper.setWrappedObject(appObject); - - return objectWrapper; - } - - @Override - public Class getAppObjectClass() { - return Object.class; - } - - @Override - public Class getInputObjectClass() { - return null; - } - }; - builder.addTranslationSpec(wrapperTranslationSpec); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_SPEC_INPUT_CLASS, contractException.getErrorType()); - - builder.clearBuilder(); - // if the translation spec has already been added (same, but different - // instances) - contractException = assertThrows(ContractException.class, () -> { - TestObjectTranslationSpec testObjectTranslationSpec1 = new TestObjectTranslationSpec(); - TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); - - builder.addTranslationSpec(testObjectTranslationSpec1).addTranslationSpec(testObjectTranslationSpec2); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); - - builder.clearBuilder(); - // if the translation spec has already been added (exact same instance) - contractException = assertThrows(ContractException.class, () -> { - TestObjectTranslationSpec testObjectTranslationSpec1 = new TestObjectTranslationSpec(); - - builder.addTranslationSpec(testObjectTranslationSpec1).addTranslationSpec(testObjectTranslationSpec1); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); - } - - public static void testAddTranslator(TranslationEngine.Builder builder) { - builder.addTranslator(TestObjectTranslator.getTranslator()); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - builder.addTranslator(null); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATOR, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - builder.addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestObjectTranslator.getTranslator()); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATOR, contractException.getErrorType()); - } - - public static void testAddParentChildClassRelationship(TranslationEngine.Builder builder) { - builder.addParentChildClassRelationship(TestAppObject.class, Object.class); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - builder.addParentChildClassRelationship(null, Object.class); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - builder.addParentChildClassRelationship(TestAppObject.class, null); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - builder.addParentChildClassRelationship(TestAppObject.class, Object.class) - .addParentChildClassRelationship(TestAppObject.class, Object.class); - }); - - assertEquals(CoreTranslationError.DUPLICATE_CLASSREF, contractException.getErrorType()); - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngine.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngine.java new file mode 100644 index 0000000..7d62de6 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngine.java @@ -0,0 +1,706 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngineBuilderBridge; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngineId; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestObjectWrapper; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.TestTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs.TestComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceError; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +public class AT_TaskitEngine { + Path basePath = ResourceHelper.getResourceDir(this.getClass()); + Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "getTaskitEngineId", args = {}) + public void testGetTaskitEngineId() { + TaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .build(); + + assertEquals(TestTaskitEngineId.TEST_ENGINE_ID, taskitEngine.getTaskitEngineId()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "init", args = {}) + public void testInit() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TaskitEngine taskitEngine = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec)) + .buildWithoutInit(); + + assertFalse(taskitEngine.isInitialized()); + assertFalse(testObjectTranslationSpec.isInitialized()); + assertFalse(testComplexObjectTranslationSpec.isInitialized()); + + taskitEngine.init(); + + assertTrue(taskitEngine.isInitialized()); + assertTrue(testObjectTranslationSpec.isInitialized()); + assertTrue(testComplexObjectTranslationSpec.isInitialized()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "isInitialized", args = {}) + public void testIsInitialized() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TaskitEngine taskitEngine = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec)) + .buildWithoutInit(); + + assertFalse(taskitEngine.isInitialized()); + + taskitEngine.init(); + assertTrue(taskitEngine.isInitialized()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "getTranslationSpecs", args = {}) + public void testGetTranslationSpecs() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + Set actualTranslationSpecs = taskitEngine.getTranslationSpecs(); + + assertTrue(actualTranslationSpecs.contains(testObjectTranslationSpec)); + assertTrue(actualTranslationSpecs.contains(testComplexObjectTranslationSpec)); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "write", args = { Path.class, Object.class }) + public void testWrite() throws IOException { + String fileName = "testEngineWrite_1-testOutput.json"; + String fileName2 = "testEngineWrite_2-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + ResourceHelper.createFile(filePath, fileName2); + + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(complexObjectTranslationSpec).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject inputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + testTaskitEngine.write(filePath.resolve(fileName), inputObject); + TestAppObject actualAppObject = testTaskitEngine.readAndTranslate(filePath.resolve(fileName), + TestInputObject.class); + assertEquals(expectedAppObject, actualAppObject); + + // preconditions + // null path + ContractException contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.write(null, inputObject); + }); + + assertEquals(TaskitError.NULL_PATH, contractException.getErrorType()); + + // file path is directory + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.write(filePath, inputObject); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // directory path is file + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.write(filePath.resolve(fileName).resolve(fileName), inputObject); + }); + + assertEquals(ResourceError.DIRECTORY_PATH_IS_FILE, contractException.getErrorType()); + + // null object + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.write(filePath.resolve(fileName), null); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "translateAndWrite", args = { Path.class, + Object.class }) + public void testTranslateAndWrite() throws IOException { + String fileName = "testEngineTranslateAndWrite_1-testOutput.json"; + String fileName2 = "testEngineTranslateAndWrite_2-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + ResourceHelper.createFile(filePath, fileName2); + + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(complexObjectTranslationSpec).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), expectedAppObject); + TestAppObject actualAppObject = testTaskitEngine.readAndTranslate(filePath.resolve(fileName), + TestInputObject.class); + assertEquals(expectedAppObject, actualAppObject); + + testTaskitEngine.translateAndWrite(filePath.resolve(fileName2), + TestObjectUtil.getChildAppFromApp(expectedAppObject), TestAppObject.class); + TestAppObject actualAppChildObject = testTaskitEngine.readAndTranslate(filePath.resolve(fileName2), + TestInputObject.class); + assertEquals(expectedAppObject, actualAppChildObject); + + // preconditions + // null path + ContractException contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(null, expectedAppObject); + }); + + assertEquals(TaskitError.NULL_PATH, contractException.getErrorType()); + + // file path is directory + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath, expectedAppObject); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // directory path is file + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName).resolve(fileName), expectedAppObject); + }); + + assertEquals(ResourceError.DIRECTORY_PATH_IS_FILE, contractException.getErrorType()); + + // null object + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), null); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + + // unknown translation spec + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), new TestAppChildObject()); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "translateAndWrite", args = { Path.class, Object.class, + Class.class }) + public void testTranslateAndWrite_Class() throws IOException { + String fileName = "testEngineTranslateAndWrite_class_1-testOutput.json"; + String fileName2 = "testEngineTranslateAndWrite_class_2-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + ResourceHelper.createFile(filePath, fileName2); + + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(complexObjectTranslationSpec).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + testTaskitEngine.translateAndWrite(filePath.resolve(fileName2), + TestObjectUtil.getChildAppFromApp(expectedAppObject), TestAppObject.class); + TestAppObject actualAppChildObject = testTaskitEngine.readAndTranslate(filePath.resolve(fileName2), + TestInputObject.class); + assertEquals(expectedAppObject, actualAppChildObject); + + // preconditions + // null path + ContractException contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(null, expectedAppObject, TestAppObject.class); + }); + + assertEquals(TaskitError.NULL_PATH, contractException.getErrorType()); + + // file path is directory + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath, expectedAppObject, TestAppObject.class); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // directory path is file + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName).resolve(fileName), expectedAppObject, + TestAppObject.class); + }); + + assertEquals(ResourceError.DIRECTORY_PATH_IS_FILE, contractException.getErrorType()); + + // null object + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), null, TestAppObject.class); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + + // null class + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), expectedAppObject, null); + }); + + assertEquals(TaskitError.NULL_CLASS_REF, contractException.getErrorType()); + + // unknown translation spec + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), new TestAppChildObject(), + TestAppChildObject.class); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "read", args = { Path.class, Class.class }) + public void testRead() throws IOException { + String fileName = "testEngineRead_1-testOutput.json"; + String fileName2 = "testEngineRead_2-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + ResourceHelper.createFile(filePath, fileName2); + + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(complexObjectTranslationSpec).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), expectedAppObject); + TestInputObject actualInputObject = testTaskitEngine.read(filePath.resolve(fileName), + TestInputObject.class); + assertEquals(expectedInputObject, actualInputObject); + + // preconditions + // null path + ContractException contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.read(null, TestInputObject.class); + }); + + assertEquals(TaskitError.NULL_PATH, contractException.getErrorType()); + + // file path is a directory + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.read(filePath, TestInputObject.class); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // unknown file + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.read(filePath.resolve("unknownFile.json"), TestInputObject.class); + }); + + assertEquals(ResourceError.UNKNOWN_FILE, contractException.getErrorType()); + + // null classref + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.read(filePath.resolve(fileName), null); + }); + + assertEquals(TaskitError.NULL_CLASS_REF, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "readAndTranslate", args = { Path.class, Class.class }) + public void testReadAndTranslate() throws IOException { + String fileName = "testEngineReadAndTranslate_1-testOutput.json"; + String fileName2 = "testEngineReadAndTranslate_2-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + ResourceHelper.createFile(filePath, fileName2); + + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(complexObjectTranslationSpec).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + testTaskitEngine.translateAndWrite(filePath.resolve(fileName), expectedAppObject); + TestAppObject actualAppObject = testTaskitEngine.readAndTranslate(filePath.resolve(fileName), + TestInputObject.class); + assertEquals(expectedAppObject, actualAppObject); + + // preconditions + // null path + ContractException contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.readAndTranslate(null, TestInputObject.class); + }); + + assertEquals(TaskitError.NULL_PATH, contractException.getErrorType()); + + // file path is a directory + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.readAndTranslate(filePath, TestInputObject.class); + }); + + assertEquals(ResourceError.FILE_PATH_IS_DIRECTORY, contractException.getErrorType()); + + // unknown file + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.readAndTranslate(filePath.resolve("unknownFile.json"), TestInputObject.class); + }); + + assertEquals(ResourceError.UNKNOWN_FILE, contractException.getErrorType()); + + // null classref + contractException = assertThrows(ContractException.class, () -> { + testTaskitEngine.readAndTranslate(filePath.resolve(fileName), null); + }); + + assertEquals(TaskitError.NULL_CLASS_REF, contractException.getErrorType()); + + // unknown translation spec + contractException = assertThrows(ContractException.class, () -> { + + TestTaskitEngine.builder().addTranslationSpec(new TestComplexObjectTranslationSpec()).build() + .readAndTranslate(filePath.resolve(fileName), TestInputObject.class); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "translateObject", args = { Object.class }) + public void testTranslateObject() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + TestInputObject actualInputObject = taskitEngine.translateObject(expectedAppObject); + assertEquals(expectedInputObject, actualInputObject); + + TestAppObject actualAppObject = taskitEngine.translateObject(expectedInputObject); + assertEquals(expectedAppObject, actualAppObject); + + // preconditions + // the contract exception for TaskitCoreError#UNKNOWN_TRANSLATION_SPEC is + // covered by the test - testGetTranslationSpecForClass + + // the passed in object is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngine.translateObject(null); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "translateObjectAsClassSafe", args = { Object.class, + Class.class }) + public void testTranslateObjectAsSafeClass() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + TestAppChildObject expectedAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); + TestInputChildObject expectedInputChildObject = TestObjectUtil + .getChildInputFromInput(expectedInputObject); + + TestInputObject actualInputChildObject = taskitEngine.translateObjectAsClassSafe( + expectedAppChildObject, + TestAppObject.class); + assertEquals(expectedInputChildObject, TestObjectUtil.getChildInputFromInput(actualInputChildObject)); + + TestAppObject actualAppChildObject = taskitEngine.translateObjectAsClassSafe( + expectedInputChildObject, + TestInputObject.class); + assertEquals(expectedAppChildObject, TestObjectUtil.getChildAppFromApp(actualAppChildObject)); + + // preconditions + // TaskitCoreError#NULL_CLASS_REF is covered by the test - + // testGetTranslationSpecForClass + // TaskitCoreError#UNKNOWN_TRANSLATION_SPEC is covered by the test - + // testGetTranslationSpecForClass + + // the passed in object is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngine.translateObjectAsClassSafe(null, Object.class); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "translateObjectAsClassUnsafe", args = { Object.class, + Class.class }) + public void testTranslateObjectAsClassUnsafe() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + // custom Translation Spec to simulate a Spec that might use a class to "wrap" + // another class + TestTranslationSpec wrapperTranslationSpec = new TestTranslationSpec() { + + @Override + protected Object translateInputObject(TestObjectWrapper inputObject) { + return inputObject.getWrappedObject(); + } + + @Override + protected TestObjectWrapper translateAppObject(Object appObject) { + TestObjectWrapper objectWrapper = new TestObjectWrapper(); + + objectWrapper.setWrappedObject(appObject); + + return objectWrapper; + } + + @Override + public Class getAppObjectClass() { + return Object.class; + } + + @Override + public Class getInputObjectClass() { + return TestObjectWrapper.class; + } + }; + + TaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .addTranslationSpec(wrapperTranslationSpec) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + TestObjectWrapper expectedWrapper = new TestObjectWrapper(); + expectedWrapper.setWrappedObject(expectedAppObject); + + TestObjectWrapper actualWrapper = taskitEngine.translateObjectAsClassUnsafe(expectedAppObject, + TestObjectWrapper.class); + + assertEquals(expectedWrapper, actualWrapper); + + Object actualAppObject = taskitEngine.translateObject(actualWrapper); + + assertEquals(expectedAppObject, actualAppObject); + + // preconditions + // TaskitCoreError#NULL_CLASS_REF is covered by the test - + // testGetTranslationSpecForClass + // TaskitCoreError#UNKNOWN_TRANSLATION_SPEC is covered by the test - + // testGetTranslationSpecForClass + + // the passed in object is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngine.translateObjectAsClassUnsafe(null, Object.class); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "getTranslationSpecForClass", args = { Class.class }) + public void testGetTranslationSpecForClass() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + + TaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + assertEquals(testObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass(TestAppObject.class)); + assertEquals(testObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass(TestInputObject.class)); + + assertEquals(testComplexObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass(TestComplexAppObject.class)); + assertEquals(testComplexObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass(TestComplexInputObject.class)); + + // preconditions + // the classRef is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngine.getTranslationSpecForClass(null); + }); + + assertEquals(TaskitError.NULL_CLASS_REF, contractException.getErrorType()); + + // no Translation Spec exists for the given class + contractException = assertThrows(ContractException.class, () -> { + taskitEngine.getTranslationSpecForClass(Object.class); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + // TODO: update test + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "hashCode", args = {}) + public void testHashCode() { + TaskitEngine taskitEngine1 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .build(); + + TaskitEngine taskitEngine2 = TestTaskitEngine.builder() + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .build(); + + TaskitEngine taskitEngine3 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .build(); + + TaskitEngine taskitEngine4 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .build(); + + // exact same, same hash code + assertEquals(taskitEngine1.hashCode(), taskitEngine1.hashCode()); + + // different translation specs + assertNotEquals(taskitEngine1.hashCode(), taskitEngine2.hashCode()); + assertNotEquals(taskitEngine1.hashCode(), taskitEngine3.hashCode()); + assertNotEquals(taskitEngine2.hashCode(), taskitEngine3.hashCode()); + assertNotEquals(taskitEngine2.hashCode(), taskitEngine4.hashCode()); + assertNotEquals(taskitEngine3.hashCode(), taskitEngine4.hashCode()); + + // same translation specs + assertEquals(taskitEngine1.hashCode(), taskitEngine4.hashCode()); + } + + // TODO: update test + @Test + @UnitTestMethod(target = TaskitEngine.class, name = "equals", args = { Object.class }) + public void testEquals() { + TaskitEngine taskitEngine1 = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec())) + .buildWithoutInit(); + + TaskitEngine taskitEngine2 = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslationSpec(new TestComplexObjectTranslationSpec())) + .buildWithoutInit(); + + TaskitEngine taskitEngine3 = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec())) + .buildWithoutInit(); + + TaskitEngine taskitEngine4 = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec())) + .buildWithoutInit(); + + TaskitEngine taskitEngine5 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .build(); + + TaskitEngine taskitEngine6 = new TaskitEngine( + TaskitEngineData.builder().addTranslationSpec(new TestObjectTranslationSpec()).build(), + new TaskitEngineId() { + + }) { + + @Override + protected void writeToFile(File file, O outputObject) throws IOException { + } + + @Override + protected I readFile(File file, Class inputClassRef) throws IOException { + return null; + } + + }; + + // exact same + assertEquals(taskitEngine1, taskitEngine1); + + // null test + assertNotEquals(taskitEngine1, null); + + // not an instance test + assertNotEquals(taskitEngine1, new Object()); + + // different id + assertNotEquals(taskitEngine1, taskitEngine6); + + // different translation specs + assertNotEquals(taskitEngine1, taskitEngine2); + assertNotEquals(taskitEngine1, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine4); + assertNotEquals(taskitEngine3, taskitEngine4); + + // same translation specs + assertEquals(taskitEngine1, taskitEngine4); + + // init vs not init + assertNotEquals(taskitEngine1, taskitEngine5); + + taskitEngine1.init(); + taskitEngine2.init(); + taskitEngine3.init(); + taskitEngine4.init(); + + // init and same translation specs + assertEquals(taskitEngine1, taskitEngine4); + + // init and different translation specs + assertNotEquals(taskitEngine1, taskitEngine2); + assertNotEquals(taskitEngine1, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine4); + assertNotEquals(taskitEngine3, taskitEngine4); + + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngineData.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngineData.java new file mode 100644 index 0000000..dee7b30 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngineData.java @@ -0,0 +1,288 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.bad.BadTranslationSpecEmptyMap; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.bad.BadTranslationSpecNullMap; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.TestComplexObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs.TestComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.TestObjectTranslator; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorContext; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; + +public class AT_TaskitEngineData { + @Test + @UnitTestMethod(target = TaskitEngineData.Builder.class, name = "build", args = {}) + public void testBuild() { + // preconditions: + // uninitialized translator + ContractException contractException = assertThrows(ContractException.class, () -> { + TaskitEngineData.builder().addTranslator(TestObjectTranslator.getTranslator()).build(); + }); + + assertEquals(TaskitError.UNINITIALIZED_TRANSLATORS, contractException.getErrorType()); + // duplicate translator + contractException = assertThrows(ContractException.class, () -> { + TaskitEngineData.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestObjectTranslator.getTranslator()) + .checkTranslatorGraph(false); + }); + + assertEquals(TaskitError.DUPLICATE_TRANSLATOR, contractException.getErrorType()); + + // missing translator + contractException = assertThrows(ContractException.class, () -> { + TaskitEngineData.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(Translator.builder() + .setTranslatorId(new TranslatorId() { + }) + .addDependency(TestComplexObjectTranslatorId.TRANSLATOR_ID) + .setInitializer((c) -> { + }).build()) + .checkTranslatorGraph(false); + }); + + assertEquals(TaskitError.MISSING_TRANSLATOR, contractException.getErrorType()); + + // circular translator dependencies + contractException = assertThrows(ContractException.class, () -> { + TranslatorId translatorId1 = new TranslatorId() { + }; + TranslatorId translatorId2 = new TranslatorId() { + }; + Translator translator1 = Translator.builder() + .setTranslatorId(translatorId1) + .addDependency(translatorId2) + .setInitializer((c) -> { + }) + .build(); + Translator translator2 = Translator.builder() + .setTranslatorId(translatorId2) + .addDependency(translatorId1) + .setInitializer((c) -> { + }) + .build(); + + TranslatorId translatorId3 = new TranslatorId() { + }; + TranslatorId translatorId4 = new TranslatorId() { + }; + Translator translator3 = Translator.builder() + .setTranslatorId(translatorId3) + .addDependency(translatorId4) + .setInitializer((c) -> { + }) + .build(); + Translator translator4 = Translator.builder() + .setTranslatorId(translatorId4) + .addDependency(translatorId3) + .setInitializer((c) -> { + }) + .build(); + + TaskitEngineData.builder() + .addTranslator(translator1) + .addTranslator(translator2) + .addTranslator(translator3) + .addTranslator(translator4) + .checkTranslatorGraph(false); + }); + + assertEquals(TaskitError.CIRCULAR_TRANSLATOR_DEPENDENCIES, contractException.getErrorType()); + + // no translation specs were added + contractException = assertThrows(ContractException.class, () -> { + TaskitEngineData.builder().build(); + }); + + assertEquals(TaskitError.NO_TRANSLATION_SPECS, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineData.Builder.class, name = "addTranslationSpec", args = { + ITranslationSpec.class }) + public void testAddTranslationSpec() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + + TaskitEngineData.Builder builder = TaskitEngineData.builder(); + + TaskitEngineData taskitEngineData = builder + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec).build(); + + // show that the translation specs are retrievable by their own app and input + // classes + assertEquals(testObjectTranslationSpec, + taskitEngineData.classToTranslationSpecMap.get(testObjectTranslationSpec.getAppObjectClass())); + assertEquals(testObjectTranslationSpec, + taskitEngineData.classToTranslationSpecMap.get(testObjectTranslationSpec.getInputObjectClass())); + + assertEquals(testComplexObjectTranslationSpec, + taskitEngineData.classToTranslationSpecMap.get(testComplexObjectTranslationSpec.getAppObjectClass())); + assertEquals(testComplexObjectTranslationSpec, + taskitEngineData.classToTranslationSpecMap.get(testComplexObjectTranslationSpec.getInputObjectClass())); + + // preconditions + // translationSpec is null + ContractException contractException = assertThrows(ContractException.class, () -> { + builder.addTranslationSpec(null); + }); + + assertEquals(TaskitError.NULL_TRANSLATION_SPEC, contractException.getErrorType()); + + // null translationSpecToClassMap + contractException = assertThrows(ContractException.class, () -> { + BadTranslationSpecNullMap badTranslationSpecNullMap = new BadTranslationSpecNullMap(); + builder.addTranslationSpec(badTranslationSpecNullMap); + }); + + assertEquals(TaskitError.NULL_TRANSLATION_SPEC_CLASS_MAP, + contractException.getErrorType()); + + // empty translationSpecToClassMap + contractException = assertThrows(ContractException.class, () -> { + BadTranslationSpecEmptyMap badTranslationSpecEmptyMap = new BadTranslationSpecEmptyMap(); + builder.addTranslationSpec(badTranslationSpecEmptyMap); + }); + + assertEquals(TaskitError.EMPTY_TRANSLATION_SPEC_CLASS_MAP, + contractException.getErrorType()); + + // if the translation spec has already been added (same, but different + // instances) + contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec1 = new TestObjectTranslationSpec(); + TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); + + TaskitEngineData.builder() + .addTranslationSpec(testObjectTranslationSpec1) + .addTranslationSpec(testObjectTranslationSpec2); + }); + + assertEquals(TaskitError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); + + // if the translation spec has already been added (exact same instance) + contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec1 = new TestObjectTranslationSpec(); + + TaskitEngineData.builder() + .addTranslationSpec(testObjectTranslationSpec1) + .addTranslationSpec(testObjectTranslationSpec1); + }); + + assertEquals(TaskitError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineData.Builder.class, name = "addTranslator", args = { Translator.class }) + public void testAddTranslator() { + Translator translator = TestObjectTranslator.getTranslator(); + TranslatorContext translatorContext = new TranslatorContext(TestTaskitEngine.builder()); + translator.initialize(translatorContext); + + TaskitEngineData.builder().addTranslator(translator); + + // preconditions + // null translator + ContractException contractException = assertThrows(ContractException.class, () -> { + TaskitEngineData.builder().addTranslator(null); + }); + + assertEquals(TaskitError.NULL_TRANSLATOR, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineData.class, name = "builder", args = {}) + public void testBuilder() { + // nothing to test + } + + // TODO: update test + @Test + @UnitTestMethod(target = TaskitEngineData.class, name = "hashCode", args = {}) + public void testHashCode() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + + TaskitEngineData taskitEngineData1 = TaskitEngineData.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TaskitEngineData taskitEngineData2 = TaskitEngineData.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TaskitEngineData taskitEngineData3 = TaskitEngineData.builder() + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + // same + assertEquals(taskitEngineData1.hashCode(), taskitEngineData1.hashCode()); + + // same exact specs + assertEquals(taskitEngineData1.hashCode(), taskitEngineData2.hashCode()); + assertEquals(taskitEngineData2.hashCode(), taskitEngineData1.hashCode()); + + // different specs + assertNotEquals(taskitEngineData1.hashCode(), taskitEngineData3.hashCode()); + assertNotEquals(taskitEngineData2.hashCode(), taskitEngineData3.hashCode()); + assertNotEquals(taskitEngineData3.hashCode(), taskitEngineData1.hashCode()); + assertNotEquals(taskitEngineData3.hashCode(), taskitEngineData2.hashCode()); + } + + // TODO: update test + @Test + @UnitTestMethod(target = TaskitEngineData.class, name = "equals", args = { Object.class }) + public void testEquals() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + + TaskitEngineData taskitEngineData1 = TaskitEngineData.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TaskitEngineData taskitEngineData2 = TaskitEngineData.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TaskitEngineData taskitEngineData3 = TaskitEngineData.builder() + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + // same + assertEquals(taskitEngineData1, taskitEngineData1); + + // not null + assertNotEquals(taskitEngineData1, null); + + // not instance of + assertNotEquals(taskitEngineData1, new Object()); + + // same exact specs + assertEquals(taskitEngineData1, taskitEngineData2); + assertEquals(taskitEngineData2, taskitEngineData1); + + // different specs + assertNotEquals(taskitEngineData1, taskitEngineData3); + assertNotEquals(taskitEngineData2, taskitEngineData3); + assertNotEquals(taskitEngineData3, taskitEngineData1); + assertNotEquals(taskitEngineData3, taskitEngineData2); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngineManager.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngineManager.java new file mode 100644 index 0000000..2d93637 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitEngineManager.java @@ -0,0 +1,567 @@ +package gov.hhs.aspr.ms.taskit.core.engine; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.io.File; +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngineBuilderBridge; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngineId; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestObjectWrapper; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.TestTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.TestComplexObjectTranslator; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.TestObjectTranslator; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +public class AT_TaskitEngineManager { + + Path basePath = ResourceHelper.getResourceDir(this.getClass()); + Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "translateObject", args = { Object.class, + TaskitEngineId.class }) + public void testTranslateObject() { + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + TestAppObject actualAppObject = taskitEngineManager.translateObject(expectedInputObject, + TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedAppObject, actualAppObject); + + TestInputObject actualInputObject = taskitEngineManager.translateObject(expectedAppObject, + TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedInputObject, actualInputObject); + // preconditions + // null taskit engine id + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObject(actualInputObject, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // null taskit engine + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObject(actualInputObject, new TaskitEngineId() { + + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // null object for translation + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObject(null, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + + // unknownTranslation spec + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObject(new Object(), TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "translateObjectAsClassSafe", args = { Object.class, + Class.class, TaskitEngineId.class }) + public void testTranslateObjectAsClassSafe() { + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestAppChildObject testAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); + + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + TestInputChildObject testInputChildObject = TestObjectUtil.getChildInputFromInput(expectedInputObject); + + TestInputObject actualInputObject = taskitEngineManager.translateObjectAsClassSafe(testAppChildObject, + TestAppObject.class, TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedInputObject, actualInputObject); + + TestAppObject actualAppObject = taskitEngineManager.translateObjectAsClassSafe(testInputChildObject, + TestInputObject.class, TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedAppObject, actualAppObject); + + // preconditions + // null taskit engine id + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassSafe(expectedAppObject, TestAppObject.class, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // null taskit engine + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassSafe(expectedAppObject, TestAppObject.class, + new TaskitEngineId() { + + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // null object for translation + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassSafe(null, + TestInputObject.class, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + + // null class ref + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassSafe(expectedAppObject, + null, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.NULL_CLASS_REF, contractException.getErrorType()); + + // unknownTranslation spec + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassSafe(expectedAppObject, + Object.class, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "translateObjectAsClassUnsafe", args = { + Object.class, + Class.class, TaskitEngineId.class }) + public void testTranslateObjectAsClassUnsafe() { + + TestTranslationSpec wrapperTranslationSpec = new TestTranslationSpec() { + + @Override + protected Object translateInputObject(TestObjectWrapper inputObject) { + return inputObject.getWrappedObject(); + } + + @Override + protected TestObjectWrapper translateAppObject(Object appObject) { + TestObjectWrapper objectWrapper = new TestObjectWrapper(); + + objectWrapper.setWrappedObject(appObject); + + return objectWrapper; + } + + @Override + public Class getAppObjectClass() { + return Object.class; + } + + @Override + public Class getInputObjectClass() { + return TestObjectWrapper.class; + } + }; + + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .addTranslationSpec(wrapperTranslationSpec) + .build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + TestObjectWrapper expectedWrapper = new TestObjectWrapper(); + expectedWrapper.setWrappedObject(expectedAppObject); + + TestObjectWrapper actualWrapper = taskitEngineManager.translateObjectAsClassUnsafe(expectedAppObject, + TestObjectWrapper.class, TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedWrapper, actualWrapper); + + // preconditions + // null taskit engine id + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassUnsafe(expectedAppObject, TestAppObject.class, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // null taskit engine + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassUnsafe(expectedAppObject, TestAppObject.class, + new TaskitEngineId() { + + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // null object for translation + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassUnsafe(null, + TestInputObject.class, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + + // null class ref + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassUnsafe(expectedAppObject, + null, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.NULL_CLASS_REF, contractException.getErrorType()); + + // unknownTranslation spec + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateObjectAsClassUnsafe(expectedAppObject, + TaskitEngine.class, TestTaskitEngineId.TEST_ENGINE_ID); + }); + + assertEquals(TaskitError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "read", args = { Path.class, Class.class, + TaskitEngineId.class }) + public void testRead() { + String fileName = "readInput-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject appObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(appObject); + + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), appObject, + TestTaskitEngineId.TEST_ENGINE_ID); + + TestInputObject actualInputObject = taskitEngineManager.read(filePath.resolve(fileName), + TestInputObject.class, TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedInputObject, actualInputObject); + + // preconditions + // only the preconditions not tested byt AT_TaskitEngine are tested here + + // null taskit engine id + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.read(filePath.resolve(fileName), TestInputObject.class, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // null taskit engine + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.read(filePath.resolve(fileName), TestInputObject.class, + new TaskitEngineId() { + + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // issue reading file + assertThrows(RuntimeException.class, () -> { + ResourceHelper.createFile(filePath, "foo.json"); + + taskitEngineManager.read(filePath.resolve("foo.json"), TestInputObject.class, + TestTaskitEngineId.TEST_ENGINE_ID); + }); + + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "readAndTranslate", args = { Path.class, Class.class, + TaskitEngineId.class }) + public void testReadAndTranslate() { + String fileName = "readInput-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()).build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, + TestTaskitEngineId.TEST_ENGINE_ID); + + TestAppObject actualAppObject = taskitEngineManager.readAndTranslate(filePath.resolve(fileName), + TestInputObject.class, TestTaskitEngineId.TEST_ENGINE_ID); + + assertEquals(expectedAppObject, actualAppObject); + + // preconditions + // only the preconditions not tested byt AT_TaskitEngine are tested here + + // null taskit engine id + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.readAndTranslate(filePath.resolve(fileName), TestInputObject.class, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // null taskit engine + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.readAndTranslate(filePath.resolve(fileName), TestInputObject.class, + new TaskitEngineId() { + + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // issue reading file + assertThrows(RuntimeException.class, () -> { + taskitEngineManager.readAndTranslate(filePath.resolve("badJson.json"), TestInputObject.class, + TestTaskitEngineId.TEST_ENGINE_ID); + }); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "write", args = { Path.class, Object.class, + TaskitEngineId.class }) + public void testWrite() { + String fileName = "write-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject inputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + taskitEngineManager.write(filePath.resolve(fileName), inputObject, TestTaskitEngineId.TEST_ENGINE_ID); + + // preconditions + // only the preconditions not tested byt AT_TaskitEngine are tested here + + // taskit engine id is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.write(filePath.resolve(fileName), inputObject, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // taskit engine is null + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.write(filePath.resolve(fileName), inputObject, new TaskitEngineId() { + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // writing the file encounters a IOException + File file = filePath.resolve(fileName).toFile(); + assertThrows(RuntimeException.class, () -> { + file.setReadOnly(); + taskitEngineManager.write(filePath.resolve(fileName), inputObject, TestTaskitEngineId.TEST_ENGINE_ID); + }); + file.setReadable(true); + file.delete(); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "translateAndWrite", args = { Path.class, + Object.class, + TaskitEngineId.class }) + public void testTranslateAndWrite() { + String fileName = "translateAndWrite-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, + TestTaskitEngineId.TEST_ENGINE_ID); + + // preconditions + // only the preconditions not tested byt AT_TaskitEngine are tested here + + // taskit engine id is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // taskit engine is null + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, new TaskitEngineId() { + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // writing the file encounters a IOException + File file = filePath.resolve(fileName).toFile(); + assertThrows(RuntimeException.class, () -> { + file.setReadOnly(); + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, + TestTaskitEngineId.TEST_ENGINE_ID); + }); + file.setReadable(true); + file.delete(); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "translateAndWrite", args = { Path.class, + Object.class, + Class.class, TaskitEngineId.class }) + public void testTranslateAndWrite_Parent() { + String fileName = "translateAndWrite-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .build(); + + TaskitEngineManager taskitEngineManager = TaskitEngineManager.builder() + .addTaskitEngine(testTaskitEngine).build(); + + TestAppObject appObject = TestObjectUtil.generateTestAppObject(); + TestAppChildObject expectedAppObject = TestObjectUtil.getChildAppFromApp(appObject); + + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, + TestAppObject.class, + TestTaskitEngineId.TEST_ENGINE_ID); + + // preconditions + // only the preconditions not tested byt AT_TaskitEngine are tested here + + // taskit engine id is null + ContractException contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, TestAppObject.class, + null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE_ID, contractException.getErrorType()); + + // taskit engine is null + contractException = assertThrows(ContractException.class, () -> { + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, TestAppObject.class, + new TaskitEngineId() { + }); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // writing the file encounters a IOException + File file = filePath.resolve(fileName).toFile(); + assertThrows(RuntimeException.class, () -> { + file.setReadOnly(); + taskitEngineManager.translateAndWrite(filePath.resolve(fileName), expectedAppObject, TestAppObject.class, + TestTaskitEngineId.TEST_ENGINE_ID); + }); + file.setReadable(true); + file.delete(); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.class, name = "builder", args = {}) + public void testBuilder() { + // nothing to test + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.Builder.class, name = "build", args = {}) + public void testBuild() { + // preconditions + // no taskit engines were added + ContractException contractException = assertThrows(ContractException.class, () -> { + TaskitEngineManager.builder().build(); + }); + + assertEquals(TaskitError.NO_TASKIT_ENGINES, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TaskitEngineManager.Builder.class, name = "addTaskitEngine", args = { + TaskitEngine.class }) + public void testAddTaskitEngine() { + TestTaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator()) + .build(); + + TaskitEngineManager.builder().addTaskitEngine(taskitEngine).build(); + + // preconditions + // taskit engine is null + ContractException contractException = assertThrows(ContractException.class, () -> { + TaskitEngineManager.builder().addTaskitEngine(null); + }); + + assertEquals(TaskitError.NULL_TASKIT_ENGINE, contractException.getErrorType()); + + // taskit engine is not initialized + contractException = assertThrows(ContractException.class, () -> { + TestTaskitEngine taskitEngine2 = new TestTaskitEngineBuilderBridge(TestTaskitEngine.builder() + .addTranslator(TestObjectTranslator.getTranslator()) + .addTranslator(TestComplexObjectTranslator.getTranslator())) + .buildWithoutInit(); + + TaskitEngineManager.builder() + .addTaskitEngine(taskitEngine2); + }); + + assertEquals(TaskitError.UNINITIALIZED_TASKIT_ENGINE, contractException.getErrorType()); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_CoreTranslationError.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitError.java similarity index 72% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_CoreTranslationError.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitError.java index 4ae5d4a..ed7c1a3 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_CoreTranslationError.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/engine/AT_TaskitError.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core; +package gov.hhs.aspr.ms.taskit.core.engine; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -10,20 +10,20 @@ import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -public class AT_CoreTranslationError { +public class AT_TaskitError { @Test - @UnitTestMethod(target = CoreTranslationError.class, name = "getDescription", args = {}) + @UnitTestMethod(target = TaskitError.class, name = "getDescription", args = {}) public void testGetDescription() { // show that each ErrorType has a non-null, non-empty description - for (CoreTranslationError coreTranslationError : CoreTranslationError.values()) { + for (TaskitError coreTranslationError : TaskitError.values()) { assertNotNull(coreTranslationError.getDescription()); assertTrue(coreTranslationError.getDescription().length() > 0); } // show that each description is unique (ignoring case as well) Set descriptions = new LinkedHashSet<>(); - for (CoreTranslationError coreTranslationError : CoreTranslationError.values()) { + for (TaskitError coreTranslationError : TaskitError.values()) { boolean isUnique = descriptions.add(coreTranslationError.getDescription().toLowerCase()); assertTrue(isUnique, coreTranslationError + " duplicates the description of another member"); } diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TestTranslationEngine.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TestTranslationEngine.java deleted file mode 100644 index 00a4a3d..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TestTranslationEngine.java +++ /dev/null @@ -1,143 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import java.io.IOException; -import java.nio.file.Path; -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.TranslationEngineTestHelper; -import gov.hhs.aspr.ms.taskit.core.TranslationEngineType; -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs.TestComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; - -public class AT_TestTranslationEngine { - Path basePath = ResourceHelper.getResourceDir(this.getClass()); - Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); - - @Test - @UnitTestMethod(target = TestTranslationEngine.class, name = "writeOutput", args = { Path.class, Object.class, - Optional.class }) - public void testWriteOutput() throws IOException { - String fileName = "writeOutputFromEngine_1-testOutput.json"; - String fileName2 = "writeOutputFromEngine_2-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - testTranslationEngine.writeOutput(filePath.resolve(fileName), expectedAppObject, Optional.empty()); - TestAppObject actualAppObject = testTranslationEngine.readInput(filePath.resolve(fileName), TestInputObject.class); - assertEquals(expectedAppObject, actualAppObject); - - testTranslationEngine.writeOutput(filePath.resolve(fileName2), TestObjectUtil.getChildAppFromApp(expectedAppObject), - Optional.of(TestAppObject.class)); - TestAppObject actualAppChildObject = testTranslationEngine.readInput(filePath.resolve(fileName2), TestInputObject.class); - assertEquals(expectedAppObject, actualAppChildObject); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.class, name = "readInput", args = { Path.class, Class.class }) - public void testReadInput() throws IOException { - String fileName = "readInputFromEngine_1-testOutput.json"; - String fileName2 = "readInputFromEngine_2-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - - TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); - TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder() - .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - testTranslationEngine.writeOutput(filePath.resolve(fileName), expectedAppObject, Optional.empty()); - TestAppObject actualAppObject = testTranslationEngine.readInput(filePath.resolve(fileName), TestInputObject.class); - assertEquals(expectedAppObject, actualAppObject); - - testTranslationEngine.writeOutput(filePath.resolve(fileName2), TestObjectUtil.getChildAppFromApp(expectedAppObject), - Optional.of(TestAppObject.class)); - TestAppObject actualAppChildObject = testTranslationEngine.readInput(filePath.resolve(fileName2), TestInputObject.class); - assertEquals(expectedAppObject, actualAppChildObject); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.class, name = "builder", args = {}) - public void testBuilder() { - assertNotNull(TestTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "build", args = {}) - public void testBuild() { - assertNotNull(TestTranslationEngine.builder().build()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "buildWithNoTranslatorInit", args = {}) - public void testBuildWithNoTranslatorInit() { - assertNotNull(TestTranslationEngine.builder().buildWithNoTranslatorInit()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "buildWithUnknownType", args = {}) - public void testBuildWithUnknownType() { - assertNotNull(TestTranslationEngine.builder().buildWithUnknownType()); - - assertEquals(TranslationEngineType.UNKNOWN, TestTranslationEngine.builder().buildWithUnknownType().getTranslationEngineType()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "buildWithoutSpecInit", args = {}) - public void testBuildWithoutSpecInit() { - assertNotNull(TestTranslationEngine.builder().buildWithoutSpecInit()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "addTranslationSpec", args = { - TranslationSpec.class }) - public void testAddTranslationSpec() { - TranslationEngineTestHelper.testAddTranslationSpec(TestTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "addTranslator", args = { Translator.class }) - public void testAddTranslator() { - TranslationEngineTestHelper.testAddTranslator(TestTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.Builder.class, name = "addParentChildClassRelationship", args = { - Class.class, Class.class }) - public void testAddParentChildClassRelationship() { - TranslationEngineTestHelper.testAddParentChildClassRelationship(TestTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.class, name = "hashCode", args = {}) - public void testHashCode() { - // covered by AT_TranslationEngine#testHashCode - } - - @Test - @UnitTestMethod(target = TestTranslationEngine.class, name = "equals", args = { Object.class }) - public void testEquals() { - // covered by AT_TranslationEngine#testEquals - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TestTranslationSpec.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TestTranslationSpec.java deleted file mode 100644 index e08d1c1..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TestTranslationSpec.java +++ /dev/null @@ -1,58 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.TranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; -import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; - -public class AT_TestTranslationSpec { - - @Test - @UnitTestConstructor(target = TestTranslationSpec.class, args = {}) - public void testConstructor() { - assertNotNull(new TestTranslationSpec() { - - @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { - return new TestAppObject(); - } - - @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { - return new TestInputObject(); - } - - @Override - public Class getAppObjectClass() { - return TestAppObject.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputObject.class; - } - - }); - } - - @Test - @UnitTestMethod(target = TestTranslationSpec.class, name = "init", args = { TranslationEngine.class }) - public void testInit() { - TestTranslationEngine testTranslationEngine = TestTranslationEngine.builder().build(); - - TestTranslationSpec testTranslationSpec = new TestObjectTranslationSpec(); - - testTranslationSpec.init(testTranslationEngine); - - assertTrue(testTranslationSpec.isInitialized()); - assertEquals(testTranslationEngine, testTranslationSpec.translationEngine); - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TranslationSpecSupport.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TranslationSpecSupport.java deleted file mode 100644 index 372c084..0000000 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TranslationSpecSupport.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; - -public class AT_TranslationSpecSupport { - - @Test - public void testTestGetTranslationSpecs() throws ClassNotFoundException { - List> translationSpecs = new ArrayList<>(); - - translationSpecs.add(new TestObjectTranslationSpec()); - - Set missingSpecs = TranslationSpecSupport.testGetTranslationSpecs(TestObjectTranslator.class, translationSpecs); - - assertTrue(missingSpecs.isEmpty()); - - missingSpecs = TranslationSpecSupport.testGetTranslationSpecs(TestObjectTranslator.class, new ArrayList<>()); - - assertTrue(missingSpecs.size() == 1); - assertTrue(missingSpecs.contains(TestObjectTranslationSpec.class.getSimpleName())); - } -} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TranslatorTestSupport.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TranslatorTestSupport.java new file mode 100644 index 0000000..b3ecc10 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/AT_TranslatorTestSupport.java @@ -0,0 +1,34 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.TestObjectTranslator; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; + +public class AT_TranslatorTestSupport { + + @Test + @UnitTestMethod(target = TranslatorTestSupport.class, name = "testGetTranslationSpecs", args = {Class.class, List.class}) + public void testTestGetTranslationSpecs() throws ClassNotFoundException { + List translationSpecs = new ArrayList<>(); + + translationSpecs.add(new TestObjectTranslationSpec()); + + Set missingSpecs = TranslatorTestSupport.testGetTranslationSpecs(TestObjectTranslator.class, translationSpecs); + + assertTrue(missingSpecs.isEmpty()); + + missingSpecs = TranslatorTestSupport.testGetTranslationSpecs(TestObjectTranslator.class, new ArrayList<>()); + + assertTrue(missingSpecs.size() == 1); + assertTrue(missingSpecs.contains(TestObjectTranslationSpec.class.getSimpleName())); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestObjectUtil.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestObjectUtil.java index 9a66c93..fb9ae42 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestObjectUtil.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/TestObjectUtil.java @@ -3,12 +3,12 @@ import java.util.ArrayList; import java.util.List; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; import gov.hhs.aspr.ms.util.random.RandomGeneratorProvider; public class TestObjectUtil { diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/AT_TestTaskitEngine.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/AT_TestTaskitEngine.java new file mode 100644 index 0000000..1586c05 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/AT_TestTaskitEngine.java @@ -0,0 +1,376 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.engine; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineData; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestObjectWrapper; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.TestTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.bad.BadTranslationSpecEmptyMap; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.bad.BadTranslationSpecNullMap; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs.TestComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.TestObjectTranslator; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorContext; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +public class AT_TestTaskitEngine { + Path basePath = ResourceHelper.getResourceDir(this.getClass()); + Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); + + @Test + @UnitTestMethod(target = TestTaskitEngine.Builder.class, name = "build", args = {}) + public void testBuild() { + assertEquals(TestTaskitEngineId.TEST_ENGINE_ID, TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()).build().getTaskitEngineId()); + } + + @Test + @UnitTestMethod(target = TestTaskitEngine.Builder.class, name = "addTranslationSpec", args = { + ITranslationSpec.class }) + public void testAddTranslationSpec() { + // see AT_TaskitEngineData.testAddTranslationSpec() + // code here is strictly for coverage, and coverage alone + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + + TestTaskitEngine.Builder builder = TestTaskitEngine.builder(); + + TestTaskitEngine taskitEngine = builder + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec).build(); + + // show that the translation specs are retrievable by their own app and input + // classes + assertEquals(testObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass(testObjectTranslationSpec.getAppObjectClass())); + assertEquals(testObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass( + testObjectTranslationSpec.getInputObjectClass())); + + assertEquals(testComplexObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass( + testComplexObjectTranslationSpec.getAppObjectClass())); + assertEquals(testComplexObjectTranslationSpec, + taskitEngine.getTranslationSpecForClass( + testComplexObjectTranslationSpec.getInputObjectClass())); + + // preconditions + // translationSpec is null + ContractException contractException = assertThrows(ContractException.class, () -> { + builder.addTranslationSpec(null); + }); + + assertEquals(TaskitError.NULL_TRANSLATION_SPEC, contractException.getErrorType()); + + // null translationSpecToClassMap + contractException = assertThrows(ContractException.class, () -> { + BadTranslationSpecNullMap badTranslationSpecNullMap = new BadTranslationSpecNullMap(); + builder.addTranslationSpec(badTranslationSpecNullMap); + }); + + assertEquals(TaskitError.NULL_TRANSLATION_SPEC_CLASS_MAP, + contractException.getErrorType()); + + // empty translationSpecToClassMap + contractException = assertThrows(ContractException.class, () -> { + BadTranslationSpecEmptyMap badTranslationSpecEmptyMap = new BadTranslationSpecEmptyMap(); + builder.addTranslationSpec(badTranslationSpecEmptyMap); + }); + + // if the translation spec has already been added (same, but different + // instances) + contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec1 = new TestObjectTranslationSpec(); + TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); + + TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec1) + .addTranslationSpec(testObjectTranslationSpec2); + }); + + assertEquals(TaskitError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); + + // if the translation spec has already been added (exact same instance) + contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec1 = new TestObjectTranslationSpec(); + + TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec1) + .addTranslationSpec(testObjectTranslationSpec1); + }); + + assertEquals(TaskitError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TestTaskitEngine.Builder.class, name = "addTranslator", args = { Translator.class }) + public void testAddTranslator() { + // see AT_TaskitEngine.testAddTranslator() + // code here is strictly for coverage, and coverage alone + Translator translator = TestObjectTranslator.getTranslator(); + TranslatorContext translatorContext = new TranslatorContext(TestTaskitEngine.builder()); + translator.initialize(translatorContext); + + TaskitEngineData.builder().addTranslator(translator); + + // preconditions + // null translator + ContractException contractException = assertThrows(ContractException.class, () -> { + TaskitEngineData.builder().addTranslator(null); + }); + + assertEquals(TaskitError.NULL_TRANSLATOR, contractException.getErrorType()); + + } + + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "builder", args = {}) + public void testBuilder() { + // nothing to test + } + + + + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "getTaskitEngineId", args = {}) + public void testGetTaskitEngineId() { + assertEquals(TestTaskitEngineId.TEST_ENGINE_ID, TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()).build().getTaskitEngineId()); + } + + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "translateObject", args = { Object.class }) + public void testTranslateObject() { + // see AT_TaskitEngine.testTranslateObject() + // code here is strictly for coverage, and coverage alone + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + TestInputObject actualInputObject = taskitEngine.translateObject(expectedAppObject); + assertEquals(expectedInputObject, actualInputObject); + + TestAppObject actualAppObject = taskitEngine.translateObject(expectedInputObject); + assertEquals(expectedAppObject, actualAppObject); + } + + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "translateObjectAsClassSafe", args = { + Object.class, + Class.class }) + public void testTranslateObjectAsClassSafe() { + // see AT_TaskitEngine.testTranslateObjectAsClassSafe() + // code here is strictly for coverage, and coverage alone + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + TestAppChildObject expectedAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); + TestInputChildObject expectedInputChildObject = TestObjectUtil + .getChildInputFromInput(expectedInputObject); + + TestInputObject actualInputChildObject = taskitEngine.translateObjectAsClassSafe( + expectedAppChildObject, + TestAppObject.class); + assertEquals(expectedInputChildObject, TestObjectUtil.getChildInputFromInput(actualInputChildObject)); + + TestAppObject actualAppChildObject = taskitEngine.translateObjectAsClassSafe( + expectedInputChildObject, + TestInputObject.class); + assertEquals(expectedAppChildObject, TestObjectUtil.getChildAppFromApp(actualAppChildObject)); + } + + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "translateObjectAsClassUnsafe", args = { + Object.class, Class.class }) + public void testTranslateObjectAsClassUnsafe() { + // see AT_TaskitEngine.testTranslateObjectAsClassUnsafe() + // code here is strictly for coverage, and coverage alone + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + // custom Translation Spec to simulate a Spec that might use a class to "wrap" + // another class + TestTranslationSpec wrapperTranslationSpec = new TestTranslationSpec() { + + @Override + protected Object translateInputObject(TestObjectWrapper inputObject) { + return inputObject.getWrappedObject(); + } + + @Override + protected TestObjectWrapper translateAppObject(Object appObject) { + TestObjectWrapper objectWrapper = new TestObjectWrapper(); + + objectWrapper.setWrappedObject(appObject); + + return objectWrapper; + } + + @Override + public Class getAppObjectClass() { + return Object.class; + } + + @Override + public Class getInputObjectClass() { + return TestObjectWrapper.class; + } + }; + + TestTaskitEngine taskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .addTranslationSpec(wrapperTranslationSpec) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + + TestObjectWrapper expectedWrapper = new TestObjectWrapper(); + expectedWrapper.setWrappedObject(expectedAppObject); + + TestObjectWrapper actualWrapper = taskitEngine.translateObjectAsClassUnsafe(expectedAppObject, + TestObjectWrapper.class); + + assertEquals(expectedWrapper, actualWrapper); + + Object actualAppObject = taskitEngine.translateObject(actualWrapper); + + assertEquals(expectedAppObject, actualAppObject); + } + + // TODO: update test + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "hashCode", args = {}) + public void testHashCode() { + // see AT_TaskitEngine.testHashCode() + // code here is strictly for coverage, and coverage alone + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTaskitEngine taskitEngine1 = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .buildWithoutInit(); + + TestTaskitEngine taskitEngine2 = TestTaskitEngine.builder() + .addTranslationSpec(testComplexObjectTranslationSpec) + .build(); + + TestTaskitEngine taskitEngine3 = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .build(); + + TestTaskitEngine taskitEngine4 = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(testComplexObjectTranslationSpec) + .buildWithoutInit(); + + // exact same, same hash code + assertEquals(taskitEngine1.hashCode(), taskitEngine1.hashCode()); + + // different translation specs + assertNotEquals(taskitEngine1.hashCode(), taskitEngine2.hashCode()); + assertNotEquals(taskitEngine1.hashCode(), taskitEngine3.hashCode()); + assertNotEquals(taskitEngine2.hashCode(), taskitEngine3.hashCode()); + assertNotEquals(taskitEngine2.hashCode(), taskitEngine4.hashCode()); + assertNotEquals(taskitEngine3.hashCode(), taskitEngine4.hashCode()); + + // same translation specs + assertEquals(taskitEngine1.hashCode(), taskitEngine4.hashCode()); + } + + // TODO: update test + @Test + @UnitTestMethod(target = TestTaskitEngine.class, name = "equals", args = { Object.class }) + public void testEquals() { + // see AT_TaskitEngine.testEquals() + // code here is strictly for coverage, and coverage alone + TaskitEngine taskitEngine1 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .buildWithoutInit(); + + TaskitEngine taskitEngine2 = TestTaskitEngine.builder() + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .buildWithoutInit(); + + TaskitEngine taskitEngine3 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .buildWithoutInit(); + + TaskitEngine taskitEngine4 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .buildWithoutInit(); + + TaskitEngine taskitEngine5 = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()) + .addTranslationSpec(new TestComplexObjectTranslationSpec()) + .build(); + + // exact same + assertEquals(taskitEngine1, taskitEngine1); + + // null test + assertNotEquals(taskitEngine1, null); + + // not an instance test + assertNotEquals(taskitEngine1, new Object()); + + // different translation specs + assertNotEquals(taskitEngine1, taskitEngine2); + assertNotEquals(taskitEngine1, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine4); + assertNotEquals(taskitEngine3, taskitEngine4); + + // same translation specs + assertEquals(taskitEngine1, taskitEngine4); + + // init vs not init + assertNotEquals(taskitEngine1, taskitEngine5); + + taskitEngine1.init(); + taskitEngine2.init(); + taskitEngine3.init(); + taskitEngine4.init(); + + // init and same translation specs + assertEquals(taskitEngine1, taskitEngine4); + + // init and different translation specs + assertNotEquals(taskitEngine1, taskitEngine2); + assertNotEquals(taskitEngine1, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine3); + assertNotEquals(taskitEngine2, taskitEngine4); + assertNotEquals(taskitEngine3, taskitEngine4); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/AT_TestTaskitEngineId.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/AT_TestTaskitEngineId.java new file mode 100644 index 0000000..8c7b749 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/AT_TestTaskitEngineId.java @@ -0,0 +1,16 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.engine; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.util.annotations.UnitTestField; + +public class AT_TestTaskitEngineId { + + @Test + @UnitTestField(target = TestTaskitEngineId.class, name = "TEST_ENGINE_ID") + public void testTestTaskitEngineId() { + assertNotNull(TestTaskitEngineId.TEST_ENGINE_ID); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngineBuilderBridge.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngineBuilderBridge.java new file mode 100644 index 0000000..91f5956 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/engine/TestTaskitEngineBuilderBridge.java @@ -0,0 +1,13 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.engine; + +public class TestTaskitEngineBuilderBridge { + private TestTaskitEngine.Builder taskitEngineBuilder; + + public TestTaskitEngineBuilderBridge(TestTaskitEngine.Builder taskitEngineBuilder) { + this.taskitEngineBuilder = taskitEngineBuilder; + } + + public TestTaskitEngine buildWithoutInit() { + return taskitEngineBuilder.buildWithoutInit(); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestAppChildObject.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestAppChildObject.java similarity index 86% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestAppChildObject.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestAppChildObject.java index f9f0d2d..ab6abd3 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestAppChildObject.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestAppChildObject.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestAppObject.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestAppObject.java similarity index 98% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestAppObject.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestAppObject.java index 588e25e..e821956 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestAppObject.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestAppObject.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -7,7 +7,6 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexAppObject.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestComplexAppObject.java similarity index 99% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexAppObject.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestComplexAppObject.java index 1d4bee4..5052fee 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexAppObject.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestComplexAppObject.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/input/AT_TestComplexInputObject.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestComplexInputObject.java similarity index 99% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/input/AT_TestComplexInputObject.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestComplexInputObject.java index cad60ff..d12bc04 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/input/AT_TestComplexInputObject.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestComplexInputObject.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/AT_TestInputChildObject.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestInputChildObject.java similarity index 85% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/AT_TestInputChildObject.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestInputChildObject.java index 47276a9..ac6888e 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/AT_TestInputChildObject.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestInputChildObject.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/AT_TestInputObject.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestInputObject.java similarity index 98% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/AT_TestInputObject.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestInputObject.java index b7699c4..a57141a 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/input/AT_TestInputObject.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestInputObject.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -7,7 +7,6 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectWrapper.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestObjectWrapper.java similarity index 96% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectWrapper.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestObjectWrapper.java index 56b2066..458bdb5 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectWrapper.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/objects/AT_TestObjectWrapper.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.objects; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotEquals; @@ -8,7 +8,6 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/bad/BadTranslationSpecEmptyMap.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/bad/BadTranslationSpecEmptyMap.java new file mode 100644 index 0000000..5a26dde --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/bad/BadTranslationSpecEmptyMap.java @@ -0,0 +1,30 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.bad; + +import java.util.LinkedHashMap; +import java.util.Map; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; + +public class BadTranslationSpecEmptyMap implements ITranslationSpec { + + @Override + public void init(TaskitEngine taskitEngine) { + throw new UnsupportedOperationException("Unimplemented method 'init'"); + } + + @Override + public T translate(Object object) { + throw new UnsupportedOperationException("Unimplemented method 'translate'"); + } + + @Override + public boolean isInitialized() { + return false; + } + + @Override + public Map, ITranslationSpec> getTranslationSpecClassMapping() { + return new LinkedHashMap<>(); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/bad/BadTranslationSpecNullMap.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/bad/BadTranslationSpecNullMap.java new file mode 100644 index 0000000..60ccfcc --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/bad/BadTranslationSpecNullMap.java @@ -0,0 +1,29 @@ +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.bad; + +import java.util.Map; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; + +public class BadTranslationSpecNullMap implements ITranslationSpec { + + @Override + public void init(TaskitEngine taskitEngine) { + throw new UnsupportedOperationException("Unimplemented method 'init'"); + } + + @Override + public T translate(Object object) { + throw new UnsupportedOperationException("Unimplemented method 'translate'"); + } + + @Override + public boolean isInitialized() { + return false; + } + + @Override + public Map, ITranslationSpec> getTranslationSpecClassMapping() { + return null; + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexTranslator.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/AT_TestComplexTranslator.java similarity index 79% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexTranslator.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/AT_TestComplexTranslator.java index 7c97248..8740517 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexTranslator.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/AT_TestComplexTranslator.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -7,8 +7,8 @@ import org.junit.jupiter.api.Test; -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.core.TranslatorId; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; public class AT_TestComplexTranslator { diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexTranslatorId.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/AT_TestComplexTranslatorId.java similarity index 84% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexTranslatorId.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/AT_TestComplexTranslatorId.java index 78bcae3..7bdfa24 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/AT_TestComplexTranslatorId.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/AT_TestComplexTranslatorId.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/translationSpecs/AT_TestComplexObjectTranslationSpec.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/specs/AT_TestComplexObjectTranslationSpec.java similarity index 82% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/translationSpecs/AT_TestComplexObjectTranslationSpec.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/specs/AT_TestComplexObjectTranslationSpec.java index 532b8e6..d25b13f 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testcomplexobject/translationSpecs/AT_TestComplexObjectTranslationSpec.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/complexobject/specs/AT_TestComplexObjectTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -6,10 +6,10 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -31,11 +31,11 @@ public void testConvertInputObject() { TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine.builder() + TestTaskitEngine.builder() .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); TestComplexAppObject actualComplexAppObject = complexObjectTranslationSpec - .convertInputObject(testComplexInputObject); + .translateInputObject(testComplexInputObject); assertEquals(expectedComplexAppObject, actualComplexAppObject); } @@ -49,11 +49,11 @@ public void testConvertAppObject() { TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine.builder() + TestTaskitEngine.builder() .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); TestComplexInputObject actualComplexInputObject = complexObjectTranslationSpec - .convertAppObject(testComplexAppObject); + .translateAppObject(testComplexAppObject); assertEquals(expectedComplexInputObject, actualComplexInputObject); } diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectTranslator.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/AT_TestObjectTranslator.java similarity index 73% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectTranslator.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/AT_TestObjectTranslator.java index d01a8d9..7fa9a57 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectTranslator.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/AT_TestObjectTranslator.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.object; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -7,9 +7,9 @@ import org.junit.jupiter.api.Test; -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.core.TranslatorId; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.TestComplexObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; public class AT_TestObjectTranslator { diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectTranslatorId.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/AT_TestObjectTranslatorId.java similarity index 85% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectTranslatorId.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/AT_TestObjectTranslatorId.java index 8e2bd69..72983d8 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/AT_TestObjectTranslatorId.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/AT_TestObjectTranslatorId.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.object; import static org.junit.jupiter.api.Assertions.assertNotNull; diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/AT_TestObjectTranslationSpec.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/specs/AT_TestObjectTranslationSpec.java similarity index 82% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/AT_TestObjectTranslationSpec.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/specs/AT_TestObjectTranslationSpec.java index 084b374..60b3a51 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/testobject/translationSpecs/AT_TestObjectTranslationSpec.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/testsupport/translation/object/specs/AT_TestObjectTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -6,10 +6,10 @@ import org.junit.jupiter.api.Test; import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.core.testsupport.TestTranslationEngine; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.translationSpecs.TestComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.input.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs.TestComplexObjectTranslationSpec; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -30,10 +30,10 @@ public void testConvertInputObject() { TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine.builder() + TestTaskitEngine.builder() .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); - TestAppObject actualAppObject = testObjectTranslationSpec.convertInputObject(testInputObject); + TestAppObject actualAppObject = testObjectTranslationSpec.translateInputObject(testInputObject); assertEquals(expectedAppObject, actualAppObject); } @@ -46,10 +46,10 @@ public void testConvertAppObject() { TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); - TestTranslationEngine.builder() + TestTaskitEngine.builder() .addTranslationSpec(testObjectTranslationSpec).addTranslationSpec(complexObjectTranslationSpec).build(); - TestInputObject actualInputObject = testObjectTranslationSpec.convertAppObject(testAppObject); + TestInputObject actualInputObject = testObjectTranslationSpec.translateAppObject(testAppObject); assertEquals(expectedInputObject, actualInputObject); } diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_TranslationSpec.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_TranslationSpec.java new file mode 100644 index 0000000..1da9878 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_TranslationSpec.java @@ -0,0 +1,566 @@ +package gov.hhs.aspr.ms.taskit.core.translation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineData; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineId; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.testsupport.TestObjectUtil; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestObjectWrapper; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.TestTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.specs.TestComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; + +public class AT_TranslationSpec { + + @Test + @UnitTestMethod(target = TranslationSpec.class, name = "init", args = { TaskitEngine.class }) + public void testInit() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec).build(); + + assertTrue(testObjectTranslationSpec.isInitialized()); + + // preconditions + // calling init more than once + ContractException contractException = assertThrows(ContractException.class, () -> { + testObjectTranslationSpec.init(testTaskitEngine); + }); + + assertEquals(TaskitError.DOUBLE_TRANSLATION_SPEC_INIT, contractException.getErrorType()); + + // given taskit engine type does not match type parameter + contractException = assertThrows(ContractException.class, () -> { + TaskitEngine taskitEngine = new TaskitEngine( + TaskitEngineData.builder().addTranslationSpec(new TestObjectTranslationSpec()).build(), + new TaskitEngineId() { + + }) { + + @Override + protected void writeToFile(File file, O outputObject) throws IOException { + + } + + @Override + protected I readFile(File file, Class inputClassRef) throws IOException { + return null; + } + + }; + + new TestObjectTranslationSpec().init(taskitEngine); + }); + + assertEquals(TaskitError.INVALID_TASKIT_ENGINE, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TranslationSpec.class, name = "isInitialized", args = {}) + public void testIsInitialized() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec).build(); + + assertTrue(testObjectTranslationSpec.isInitialized()); + + assertFalse(new TestObjectTranslationSpec().isInitialized()); + } + + @Test + @UnitTestMethod(target = TranslationSpec.class, name = "translate", args = { Object.class }) + public void testTranslate() { + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + TestComplexObjectTranslationSpec complexObjectTranslationSpec = new TestComplexObjectTranslationSpec(); + TestTranslationSpec wrapperTranslationSpec = new TestTranslationSpec() { + + @Override + protected Object translateInputObject(TestObjectWrapper inputObject) { + return inputObject.getWrappedObject(); + } + + @Override + protected TestObjectWrapper translateAppObject(Object appObject) { + TestObjectWrapper objectWrapper = new TestObjectWrapper(); + + objectWrapper.setWrappedObject(appObject); + + return objectWrapper; + } + + @Override + public Class getAppObjectClass() { + return Object.class; + } + + @Override + public Class getInputObjectClass() { + return TestObjectWrapper.class; + } + }; + + TestTranslationSpec wrapperTranslationSpec2 = new TestTranslationSpec() { + + @Override + protected TestObjectWrapper translateInputObject(Object inputObject) { + TestObjectWrapper testObjectWrapper = new TestObjectWrapper(); + testObjectWrapper.setWrappedObject(inputObject); + return testObjectWrapper; + } + + @Override + protected Object translateAppObject(TestObjectWrapper appObject) { + return appObject.getWrappedObject(); + } + + @Override + public Class getAppObjectClass() { + return TestObjectWrapper.class; + } + + @Override + public Class getInputObjectClass() { + return Object.class; + } + }; + + TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec) + .addTranslationSpec(complexObjectTranslationSpec) + .addTranslationSpec(wrapperTranslationSpec) + .addTranslationSpec(wrapperTranslationSpec2) + .build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + // shouldTranslateAsApp + TestInputObject actualInputObject = testObjectTranslationSpec.translate(expectedAppObject); + assertEquals(expectedInputObject, actualInputObject); + + // shouldTranslateAsIn + TestAppObject actualAppObject = testObjectTranslationSpec.translate(expectedInputObject); + assertEquals(expectedAppObject, actualAppObject); + + TestAppChildObject expectedAppChildObject = TestObjectUtil.getChildAppFromApp(expectedAppObject); + TestInputChildObject expectedInputChildObject = TestObjectUtil.getChildInputFromInput(expectedInputObject); + + // shouldTranslateAsApp + TestInputObject actualInputChildObject = testObjectTranslationSpec.translate(expectedAppChildObject); + assertEquals(expectedInputChildObject, TestObjectUtil.getChildInputFromInput(actualInputChildObject)); + + // shouldTranslateAsIn + TestAppObject actualAppChildObject = testObjectTranslationSpec.translate(expectedInputChildObject); + assertEquals(expectedAppChildObject, TestObjectUtil.getChildAppFromApp(actualAppChildObject)); + + // for code coverage + Object wrappedObj = wrapperTranslationSpec.translate(new TestObjectWrapper()); + assertNull(wrappedObj); + + wrappedObj = wrapperTranslationSpec2.translate(new TestObjectWrapper()); + assertNull(wrappedObj); + + // precondition + // TranslationSpec not initialized + ContractException contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); + testObjectTranslationSpec2.translate(new TestAppObject()); + }); + + assertEquals(TaskitError.UNINITIALIZED_TRANSLATION_SPEC, contractException.getErrorType()); + + // object is null + contractException = assertThrows(ContractException.class, () -> { + testObjectTranslationSpec.translate(null); + }); + + assertEquals(TaskitError.NULL_OBJECT_FOR_TRANSLATION, contractException.getErrorType()); + + // unknown object + contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); + TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec2) + .build(); + + testObjectTranslationSpec2.translate(new Object()); + }); + + assertEquals(TaskitError.UNKNOWN_OBJECT, contractException.getErrorType()); + + // unknown object 2 + contractException = assertThrows(ContractException.class, () -> { + TestObjectTranslationSpec testObjectTranslationSpec2 = new TestObjectTranslationSpec(); + TestTaskitEngine.builder() + .addTranslationSpec(testObjectTranslationSpec2) + .build(); + + testObjectTranslationSpec2.translate(new TestComplexInputObject()); + }); + + assertEquals(TaskitError.UNKNOWN_OBJECT, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = TranslationSpec.class, name = "getTranslationSpecClassMapping", args = {}) + public void testGetTranslationSpecClassMapping() { + Map, ITranslationSpec> expectedMapping = new LinkedHashMap<>(); + TestObjectTranslationSpec testObjectTranslationSpec = new TestObjectTranslationSpec(); + + expectedMapping.put(testObjectTranslationSpec.getAppObjectClass(), testObjectTranslationSpec); + expectedMapping.put(testObjectTranslationSpec.getInputObjectClass(), testObjectTranslationSpec); + + assertEquals(expectedMapping, testObjectTranslationSpec.getTranslationSpecClassMapping()); + } + + @Test + @UnitTestMethod(target = TranslationSpec.class, name = "hashCode", args = {}) + public void testHashCode() { + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(new TestComplexObjectTranslationSpec()).build(); + // base + TranslationSpec translationSpecA = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppObject translateInputObject(TestInputObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputObject translateAppObject(TestAppObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputObject.class; + } + + }; + + // same input class, different app class + TranslationSpec translationSpecB = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppChildObject translateInputObject(TestInputObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputObject translateAppObject(TestAppChildObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppChildObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputObject.class; + } + + }; + + // same app class, different input class + TranslationSpec translationSpecC = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppObject translateInputObject(TestInputChildObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputChildObject translateAppObject(TestAppObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputChildObject.class; + } + + }; + + // different app and different input class + TranslationSpec translationSpecD = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppChildObject translateInputObject(TestInputChildObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputChildObject translateAppObject(TestAppChildObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppChildObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputChildObject.class; + } + + }; + + // duplicate of the base + TranslationSpec translationSpecE = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppObject translateInputObject(TestInputObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputObject translateAppObject(TestAppObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputObject.class; + } + + }; + + // init the duplicate base + translationSpecE.init(testTaskitEngine); + + // same exact object should be equal + assertEquals(translationSpecA.hashCode(), translationSpecA.hashCode()); + + // different types of objects should not be equal + assertNotEquals(translationSpecA.hashCode(), new Object().hashCode()); + + // different app class should not be equal + assertNotEquals(translationSpecA.hashCode(), translationSpecB.hashCode()); + + // different input class should not be equal + assertNotEquals(translationSpecA.hashCode(), translationSpecC.hashCode()); + + // different input and different app class should not be equal + assertNotEquals(translationSpecA.hashCode(), translationSpecD.hashCode()); + + // if one is initialized and the other is not, they should not be equal + assertNotEquals(translationSpecA.hashCode(), translationSpecE.hashCode()); + + // init base + translationSpecA.init(testTaskitEngine); + + // if all above are equal, then the two specs are equal + assertEquals(translationSpecA.hashCode(), translationSpecE.hashCode()); + } + + @Test + @UnitTestMethod(target = TranslationSpec.class, name = "equals", args = { Object.class }) + public void testEquals() { + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(new TestComplexObjectTranslationSpec()).build(); + // base + TranslationSpec translationSpecA = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppObject translateInputObject(TestInputObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputObject translateAppObject(TestAppObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputObject.class; + } + + }; + + // same input class, different app class + TranslationSpec translationSpecB = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppChildObject translateInputObject(TestInputObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputObject translateAppObject(TestAppChildObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppChildObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputObject.class; + } + + }; + + // same app class, different input class + TranslationSpec translationSpecC = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppObject translateInputObject(TestInputChildObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputChildObject translateAppObject(TestAppObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputChildObject.class; + } + + }; + + // different app and different input class + TranslationSpec translationSpecD = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppChildObject translateInputObject(TestInputChildObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputChildObject translateAppObject(TestAppChildObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppChildObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputChildObject.class; + } + + }; + + // duplicate of the base + TranslationSpec translationSpecE = new TranslationSpec<>( + TestTaskitEngine.class) { + + @Override + protected TestAppObject translateInputObject(TestInputObject inputObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateInputObject'"); + } + + @Override + protected TestInputObject translateAppObject(TestAppObject appObject) { + throw new UnsupportedOperationException("Unimplemented method 'translateAppObject'"); + } + + @Override + public Class getAppObjectClass() { + return TestAppObject.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputObject.class; + } + + }; + + // init the duplicate base + translationSpecE.init(testTaskitEngine); + + // same exact object should be equal + assertEquals(translationSpecA, translationSpecA); + + // null object should not be equal + assertNotEquals(translationSpecA, null); + + // different types of objects should not be equal + assertNotEquals(translationSpecA, new Object()); + + // different app class should not be equal + assertNotEquals(translationSpecA, translationSpecB); + + // different input class should not be equal + assertNotEquals(translationSpecA, translationSpecC); + + // different input and different app class should not be equal + assertNotEquals(translationSpecA, translationSpecD); + + // if one is initialized and the other is not, they should not be equal + assertNotEquals(translationSpecA, translationSpecE); + + // init base + translationSpecA.init(testTaskitEngine); + + // if all above are equal, then the two specs are equal + assertEquals(translationSpecA, translationSpecE); + } +} diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_Translator.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_Translator.java similarity index 77% rename from core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_Translator.java rename to core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_Translator.java index ad0ca24..868a979 100644 --- a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/AT_Translator.java +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_Translator.java @@ -1,9 +1,11 @@ -package gov.hhs.aspr.ms.taskit.core; +package gov.hhs.aspr.ms.taskit.core.translation; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.LinkedHashSet; import java.util.Set; @@ -11,25 +13,17 @@ import org.junit.jupiter.api.Test; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexObjectTranslatorId; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.TestComplexObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.TestObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.wrappers.MutableBoolean; public class AT_Translator { - @Test - @UnitTestMethod(target = Translator.class, name = "getInitializer", args = {}) - public void testGetInitializer() { - Consumer expectedInitializer = (translatorContext) -> { - }; - Translator testTranslator = Translator.builder().setInitializer(expectedInitializer) - .setTranslatorId(new TranslatorId() { - }).build(); - - assertEquals(expectedInitializer, testTranslator.getInitializer()); - } - @Test @UnitTestMethod(target = Translator.class, name = "getTranslatorId", args = {}) public void testGetTranslatorId() { @@ -59,6 +53,49 @@ public void testGetTranslatorDependencies() { assertEquals(expectedDependencies, actualDependencies); } + @Test + @UnitTestMethod(target = Translator.class, name = "initialize", args = { TranslatorContext.class }) + public void testInitialize() { + TranslatorId expectedTranslatorId = new TranslatorId() { + }; + + MutableBoolean initBool = new MutableBoolean(false); + + Translator testTranslator = Translator.builder() + .setInitializer((c) -> { + initBool.setValue(true); + }) + .setTranslatorId(expectedTranslatorId) + .build(); + + testTranslator.initialize(new TranslatorContext(TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()))); + + assertTrue(initBool.getValue()); + assertTrue(testTranslator.isInitialized()); + } + + @Test + @UnitTestMethod(target = Translator.class, name = "isInitialized", args = {}) + public void testIsInitialized() { + TranslatorId expectedTranslatorId = new TranslatorId() { + }; + + Translator testTranslator = Translator.builder() + .setInitializer((c) -> { + }) + .setTranslatorId(expectedTranslatorId) + .build(); + + assertFalse(testTranslator.isInitialized()); + + // initialize + testTranslator.initialize(new TranslatorContext(TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()))); + + assertTrue(testTranslator.isInitialized()); + } + @Test @UnitTestMethod(target = Translator.class, name = "hashCode", args = {}) public void testHashCode() { @@ -160,7 +197,7 @@ public void testBuild() { Translator.builder().setTranslatorId(translatorIdA).build(); }); - assertEquals(CoreTranslationError.NULL_INIT_CONSUMER, contractException.getErrorType()); + assertEquals(TaskitError.NULL_INIT_CONSUMER, contractException.getErrorType()); // null translatorId contractException = assertThrows(ContractException.class, () -> { @@ -168,7 +205,7 @@ public void testBuild() { }).build(); }); - assertEquals(CoreTranslationError.NULL_TRANSLATOR_ID, contractException.getErrorType()); + assertEquals(TaskitError.NULL_TRANSLATOR_ID, contractException.getErrorType()); } @Test @@ -187,7 +224,7 @@ public void testSetTranslatorId() { Translator.builder().setTranslatorId(null); }); - assertEquals(CoreTranslationError.NULL_TRANSLATOR_ID, contractException.getErrorType()); + assertEquals(TaskitError.NULL_TRANSLATOR_ID, contractException.getErrorType()); } @Test @@ -207,7 +244,7 @@ public void testSetInitializer() { Translator.builder().setInitializer(null); }); - assertEquals(CoreTranslationError.NULL_INIT_CONSUMER, contractException.getErrorType()); + assertEquals(TaskitError.NULL_INIT_CONSUMER, contractException.getErrorType()); } @Test @@ -233,7 +270,7 @@ public void testAddDependency() { Translator.builder().addDependency(null); }); - assertEquals(CoreTranslationError.NULL_DEPENDENCY, contractException.getErrorType()); + assertEquals(TaskitError.NULL_DEPENDENCY, contractException.getErrorType()); // duplicate dependency contractException = assertThrows(ContractException.class, () -> { @@ -241,6 +278,6 @@ public void testAddDependency() { .addDependency(TestObjectTranslatorId.TRANSLATOR_ID); }); - assertEquals(CoreTranslationError.DUPLICATE_DEPENDENCY, contractException.getErrorType()); + assertEquals(TaskitError.DUPLICATE_DEPENDENCY, contractException.getErrorType()); } } diff --git a/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_TranslatorContext.java b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_TranslatorContext.java new file mode 100644 index 0000000..7088ab3 --- /dev/null +++ b/core/src/test/java/gov/hhs/aspr/ms/taskit/core/translation/AT_TranslatorContext.java @@ -0,0 +1,62 @@ + +package gov.hhs.aspr.ms.taskit.core.translation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.engine.ITaskitEngineBuilder; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; + +public class AT_TranslatorContext { + + @Test + @UnitTestConstructor(target = TranslatorContext.class, args = { ITaskitEngineBuilder.class }) + public void testConstructor() { + TranslatorContext translatorContext = new TranslatorContext(TestTaskitEngine.builder()); + + assertNotNull(translatorContext); + } + + private class BadEngineBuilder implements ITaskitEngineBuilder { + + @Override + public ITaskitEngineBuilder addTranslationSpec(ITranslationSpec translationSpec) { + return this; + } + + @Override + public ITaskitEngineBuilder addTranslator(Translator translator) { + return this; + } + + } + + @Test + @UnitTestMethod(target = TranslatorContext.class, name = "getTaskitEngineBuilder", args = { Class.class }) + public void testGetTaskitEngineBuilder() { + TestTaskitEngine.Builder expectedBuilder = TestTaskitEngine.builder(); + + TranslatorContext translatorContext = new TranslatorContext(expectedBuilder); + + TestTaskitEngine.Builder actualBuilder = translatorContext + .getTaskitEngineBuilder(TestTaskitEngine.Builder.class); + assertTrue(expectedBuilder == actualBuilder); + + // preconditions + // invalid class ref + ContractException contractException = assertThrows(ContractException.class, () -> { + translatorContext.getTaskitEngineBuilder(BadEngineBuilder.class); + }); + + assertEquals(TaskitError.INVALID_TASKIT_ENGINE_BUILDER_CLASS_REF, contractException.getErrorType()); + } + +} diff --git a/core/src/test/resources/badJson.json b/core/src/test/resources/badJson.json new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index 904f46d..faeabee 100644 --- a/pom.xml +++ b/pom.xml @@ -51,7 +51,7 @@ - 4.1.1 + 5.0.0 UTF-8 @@ -60,18 +60,18 @@ 1.6.0 - 3.2.5 + 3.4.0 3.3.1 3.1.2 3.1.2 - 3.7.0 - 3.2.4 - 0.4.0 + 3.8.0 + 3.2.5 + 0.5.0 2.11.0 - 4.2.1 - 5.10.2 + 4.3.0 + 5.11.0 0.8.12 @@ -87,7 +87,6 @@ gov.hhs.aspr.ms util ${util.version} - provided org.codehaus.plexus @@ -314,6 +313,14 @@ -Xmaxwarns 65536 + + + implNote + a + Implementation Note: + + + ${project.build.sourceDirectory} diff --git a/protobuf/pom.xml b/protobuf/pom.xml index b589cb9..fcfbdf4 100644 --- a/protobuf/pom.xml +++ b/protobuf/pom.xml @@ -11,7 +11,6 @@ - gov.hhs.aspr.ms.taskit protobuf jar @@ -35,8 +34,8 @@ 1.4.1 - 3.25.3 - 3.25.3 + 3.25.4 + 3.25.4 @@ -164,17 +163,6 @@ - - org.sonatype.central - central-publishing-maven-plugin - true - - central - true - ASPR MS Taskit Protobuf - - - org.sonatype.central central-publishing-maven-plugin @@ -195,12 +183,28 @@ com/google/type/*.class - **/input/**/*.class + gov/hhs/aspr/ms/taskit/protobuf/objects/*.class + gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/*.class + + javadoc + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + ${project.build.sourceDirectory}:${project.build.directory}/generated-sources/protobuf/java + + + + + \ No newline at end of file diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/PrimitiveTranslationSpecs.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/PrimitiveTranslationSpecs.java deleted file mode 100644 index 8eecc04..0000000 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/PrimitiveTranslationSpecs.java +++ /dev/null @@ -1,177 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf; - -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.Set; - -import com.google.protobuf.Any; -import com.google.protobuf.BoolValue; -import com.google.protobuf.Descriptors.Descriptor; -import com.google.protobuf.DoubleValue; -import com.google.protobuf.FloatValue; -import com.google.protobuf.Int32Value; -import com.google.protobuf.Int64Value; -import com.google.protobuf.StringValue; -import com.google.protobuf.UInt32Value; -import com.google.protobuf.UInt64Value; -import com.google.type.Date; - -import gov.hhs.aspr.ms.taskit.protobuf.input.WrapperEnumValue; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.AnyTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.BooleanTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.DateTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.DoubleTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.EnumTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.FloatTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.IntegerTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.LongTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.StringTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.UIntegerTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.ULongTranslationSpec; - -/** - * This is a helper class that encompasses all of the primitive translation - * specs needed for converting to/from the Protobuf {@link Any} type. - */ -class PrimitiveTranslationSpecs { - PrimitiveTranslationSpecs() { - } - - final BooleanTranslationSpec BOOLEAN_TRANSLATOR_SPEC = new BooleanTranslationSpec(); - final IntegerTranslationSpec INT32_TRANSLATOR_SPEC = new IntegerTranslationSpec(); - final UIntegerTranslationSpec UINT32_TRANSLATOR_SPEC = new UIntegerTranslationSpec(); - final LongTranslationSpec INT64_TRANSLATOR_SPEC = new LongTranslationSpec(); - final ULongTranslationSpec UINT64_TRANSLATOR_SPEC = new ULongTranslationSpec(); - final StringTranslationSpec STRING_TRANSLATOR_SPEC = new StringTranslationSpec(); - final FloatTranslationSpec FLOAT_TRANSLATOR_SPEC = new FloatTranslationSpec(); - final DoubleTranslationSpec DOUBLE_TRANSLATOR_SPEC = new DoubleTranslationSpec(); - final DateTranslationSpec DATE_TRANSLATOR_SPEC = new DateTranslationSpec(); - final EnumTranslationSpec ENUM_TRANSLATOR_SPEC = new EnumTranslationSpec(); - final AnyTranslationSpec ANY_TRANSLATOR_SPEC = new AnyTranslationSpec(); - - /** - * Returns a set of Protobuf Message {@link Descriptor}s for each of the - * Primitive TranslationSpecs. A Descriptor is to a Protobuf Message as Class is - * to a Java Object. - *
  • Note: as mentioned in the Class javadoc, these Primitive TranslationSpecs - * and their Descriptors are exclusively used to facilitate converting to/from a - * Protobuf {@link Any} type - */ - Set getPrimitiveDescriptors() { - Set set = new LinkedHashSet<>(); - - set.add(BoolValue.getDefaultInstance().getDescriptorForType()); - set.add(Int32Value.getDefaultInstance().getDescriptorForType()); - set.add(UInt32Value.getDefaultInstance().getDescriptorForType()); - set.add(Int64Value.getDefaultInstance().getDescriptorForType()); - set.add(UInt64Value.getDefaultInstance().getDescriptorForType()); - set.add(StringValue.getDefaultInstance().getDescriptorForType()); - set.add(FloatValue.getDefaultInstance().getDescriptorForType()); - set.add(DoubleValue.getDefaultInstance().getDescriptorForType()); - set.add(Date.getDefaultInstance().getDescriptorForType()); - set.add(WrapperEnumValue.getDefaultInstance().getDescriptorForType()); - - return set; - } - - /** - * Returns a set of {@link ProtobufTranslationSpec}s that includes each of the - * Primitive TranslationSpecs. - *
  • Note: as mentioned in the Class javadoc, these Primitive TranslationSpecs - * are exclusively used to facilitate converting to/from a Protobuf {@link Any} - * type - */ - Set> getPrimitiveTranslatorSpecs() { - Set> set = new LinkedHashSet<>(); - - set.addAll(getPrimitiveInputTranslatorSpecMap().values()); - set.addAll(getPrimitiveObjectTranslatorSpecMap().values()); - - return set; - } - - /** - * Returns a map of typeUrl to Class that includes each of the Primitive - * TranslationSpecs. - *
  • Note: as mentioned in the Class javadoc, these Primitive TranslationSpecs - * and their typeUrls are exclusively used to facilitate converting to/from a - * Protobuf {@link Any} type - */ - Map> getPrimitiveTypeUrlToClassMap() { - Map> map = new LinkedHashMap<>(); - - map.put(BoolValue.getDefaultInstance().getDescriptorForType().getFullName(), - BOOLEAN_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(Int32Value.getDefaultInstance().getDescriptorForType().getFullName(), - INT32_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(UInt32Value.getDefaultInstance().getDescriptorForType().getFullName(), - UINT32_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(Int64Value.getDefaultInstance().getDescriptorForType().getFullName(), - INT64_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(UInt64Value.getDefaultInstance().getDescriptorForType().getFullName(), - UINT64_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(StringValue.getDefaultInstance().getDescriptorForType().getFullName(), - STRING_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(FloatValue.getDefaultInstance().getDescriptorForType().getFullName(), - FLOAT_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(DoubleValue.getDefaultInstance().getDescriptorForType().getFullName(), - DOUBLE_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(Date.getDefaultInstance().getDescriptorForType().getFullName(), - DATE_TRANSLATOR_SPEC.getInputObjectClass()); - map.put(WrapperEnumValue.getDefaultInstance().getDescriptorForType().getFullName(), - ENUM_TRANSLATOR_SPEC.getInputObjectClass()); - - return map; - } - - /** - * Returns a map of {@link Class} to {@link ProtobufTranslationSpec} that - * includes each of the Primitive TranslationSpecs. This map is exclusively a - * map of the inputObjectClass to the TranslationSpec. - *
  • Note: as mentioned in the Class javadoc, these Primitive TranslationSpecs - * and their inputObjectClasses are exclusively used to facilitate converting - * to/from a Protobuf {@link Any} type - */ - Map, ProtobufTranslationSpec> getPrimitiveInputTranslatorSpecMap() { - Map, ProtobufTranslationSpec> map = new LinkedHashMap<>(); - - map.put(BOOLEAN_TRANSLATOR_SPEC.getInputObjectClass(), BOOLEAN_TRANSLATOR_SPEC); - map.put(INT32_TRANSLATOR_SPEC.getInputObjectClass(), INT32_TRANSLATOR_SPEC); - map.put(UINT32_TRANSLATOR_SPEC.getInputObjectClass(), UINT32_TRANSLATOR_SPEC); - map.put(INT64_TRANSLATOR_SPEC.getInputObjectClass(), INT64_TRANSLATOR_SPEC); - map.put(UINT64_TRANSLATOR_SPEC.getInputObjectClass(), UINT64_TRANSLATOR_SPEC); - map.put(STRING_TRANSLATOR_SPEC.getInputObjectClass(), STRING_TRANSLATOR_SPEC); - map.put(FLOAT_TRANSLATOR_SPEC.getInputObjectClass(), FLOAT_TRANSLATOR_SPEC); - map.put(DOUBLE_TRANSLATOR_SPEC.getInputObjectClass(), DOUBLE_TRANSLATOR_SPEC); - map.put(DATE_TRANSLATOR_SPEC.getInputObjectClass(), DATE_TRANSLATOR_SPEC); - map.put(ENUM_TRANSLATOR_SPEC.getInputObjectClass(), ENUM_TRANSLATOR_SPEC); - map.put(ANY_TRANSLATOR_SPEC.getInputObjectClass(), ANY_TRANSLATOR_SPEC); - - return map; - } - - /** - * Returns a map of {@link Class} to {@link ProtobufTranslationSpec} that - * includes each of the Primitive TranslationSpecs. This map is exclusively a - * map of the appObjectClass to the TranslationSpec. - *
  • Note: as mentioned in the Class javadoc, these Primitive TranslationSpecs - * and their appObjectClasses are exclusively used to facilitate converting - * to/from a Protobuf {@link Any} type - */ - Map, ProtobufTranslationSpec> getPrimitiveObjectTranslatorSpecMap() { - Map, ProtobufTranslationSpec> map = new LinkedHashMap<>(); - - // no java version of unsigned int nor unsigned long - map.put(BOOLEAN_TRANSLATOR_SPEC.getAppObjectClass(), BOOLEAN_TRANSLATOR_SPEC); - map.put(INT32_TRANSLATOR_SPEC.getAppObjectClass(), INT32_TRANSLATOR_SPEC); - map.put(INT64_TRANSLATOR_SPEC.getAppObjectClass(), INT64_TRANSLATOR_SPEC); - map.put(STRING_TRANSLATOR_SPEC.getAppObjectClass(), STRING_TRANSLATOR_SPEC); - map.put(FLOAT_TRANSLATOR_SPEC.getAppObjectClass(), FLOAT_TRANSLATOR_SPEC); - map.put(DOUBLE_TRANSLATOR_SPEC.getAppObjectClass(), DOUBLE_TRANSLATOR_SPEC); - map.put(DATE_TRANSLATOR_SPEC.getAppObjectClass(), DATE_TRANSLATOR_SPEC); - map.put(ENUM_TRANSLATOR_SPEC.getAppObjectClass(), ENUM_TRANSLATOR_SPEC); - - return map; - } -} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufTranslationEngine.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufTranslationEngine.java deleted file mode 100644 index b71fa5d..0000000 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufTranslationEngine.java +++ /dev/null @@ -1,506 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf; - -import java.io.BufferedWriter; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Reader; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import com.google.protobuf.Any; -import com.google.protobuf.Descriptors.Descriptor; -import com.google.protobuf.Descriptors.FieldDescriptor; -import com.google.protobuf.Message; -import com.google.protobuf.ProtocolMessageEnum; -import com.google.protobuf.util.JsonFormat; -import com.google.protobuf.util.JsonFormat.Parser; -import com.google.protobuf.util.JsonFormat.Printer; -import com.google.protobuf.util.JsonFormat.TypeRegistry; - -import gov.hhs.aspr.ms.taskit.core.CoreTranslationError; -import gov.hhs.aspr.ms.taskit.core.TranslationEngine; -import gov.hhs.aspr.ms.taskit.core.TranslationEngineType; -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.AnyTranslationSpec; -import gov.hhs.aspr.ms.util.errors.ContractException; - -/** - * Protobuf TranslationEngine that allows for conversion between POJOs and - * Protobuf Messages, extends {@link TranslationEngine} - */ -public final class ProtobufTranslationEngine extends TranslationEngine { - private final Data data; - - private ProtobufTranslationEngine(Data data) { - super(data); - this.data = data; - } - - private final static class Data extends TranslationEngine.Data { - // this is used specifically for Any message types to pack and unpack them - private final Map> typeUrlToClassMap = new LinkedHashMap<>(); - - // these two fields are used for reading and writing Protobuf Messages to/from - // JSON - private Parser jsonParser; - private Printer jsonPrinter; - - private Data() { - super(); - /* - * automatically include all Primitive TranslationSpecs Note that these - * TranslationSpecs are specifically used for converting primitive types that - * are packed inside an Any Message for example, a boolean wrapped in an Any - * Message is of type BoolValue, and so there is a translationSpec to convert - * from a BoolValue to a boolean and vice versa - */ - PrimitiveTranslationSpecs primitiveTranslationSpecs = new PrimitiveTranslationSpecs(); - this.typeUrlToClassMap.putAll(primitiveTranslationSpecs.getPrimitiveTypeUrlToClassMap()); - this.classToTranslationSpecMap.putAll(primitiveTranslationSpecs.getPrimitiveInputTranslatorSpecMap()); - this.classToTranslationSpecMap.putAll(primitiveTranslationSpecs.getPrimitiveObjectTranslatorSpecMap()); - this.translationSpecs.addAll(primitiveTranslationSpecs.getPrimitiveTranslatorSpecs()); - this.translationEngineType = TranslationEngineType.PROTOBUF; - } - } - - public final static class Builder extends TranslationEngine.Builder { - private ProtobufTranslationEngine.Data data; - private Set descriptorSet = new LinkedHashSet<>(); - private final Set defaultValueFieldsToPrint = new LinkedHashSet<>(); - private boolean ignoringUnknownFields = true; - private boolean includingDefaultValueFields = false; - - private Builder(ProtobufTranslationEngine.Data data) { - super(data); - this.data = data; - } - - /** - * returns a new instance of a ProtobufTranslationEngine that has a jsonParser - * and jsonWriter that include all the typeUrls for all added TranslationSpecs - * and their respective Protobuf Message types - */ - @Override - public ProtobufTranslationEngine build() { - initTranslators(); - - TypeRegistry.Builder typeRegistryBuilder = TypeRegistry.newBuilder(); - this.descriptorSet.addAll(new PrimitiveTranslationSpecs().getPrimitiveDescriptors()); - - this.descriptorSet.forEach((descriptor) -> { - typeRegistryBuilder.add(descriptor); - }); - - TypeRegistry registry = typeRegistryBuilder.build(); - - Parser parser = JsonFormat.parser().usingTypeRegistry(registry); - if (this.ignoringUnknownFields) { - parser = parser.ignoringUnknownFields(); - } - this.data.jsonParser = parser; - - Printer printer = JsonFormat.printer().usingTypeRegistry(registry); - - if (!this.defaultValueFieldsToPrint.isEmpty()) { - printer = printer.includingDefaultValueFields(this.defaultValueFieldsToPrint); - } - - if (this.includingDefaultValueFields) { - printer = printer.includingDefaultValueFields(); - } - this.data.jsonPrinter = printer; - - ProtobufTranslationEngine translationEngine = new ProtobufTranslationEngine(this.data); - - translationEngine.initTranslationSpecs(); - - return translationEngine; - } - - /** - * Whether the jsonParser should ignore fields in the JSON that don't exist in - * the Protobuf Message. defaults to true - */ - public Builder setIgnoringUnknownFields(boolean ignoringUnknownFields) { - this.ignoringUnknownFields = ignoringUnknownFields; - return this; - } - - /** - * Whether the jsonWriter should blanket print all values that are default. The - * default values can be found here: - * https://protobuf.dev/programming-guides/proto3/#default defaults to false - */ - public Builder setIncludingDefaultValueFields(boolean includingDefaultValueFields) { - this.includingDefaultValueFields = includingDefaultValueFields; - return this; - } - - /** - * Contrary to {@link Builder#setIncludingDefaultValueFields(boolean)} which - * will either print all default values or not, this will set a specific field - * to print the default value for - */ - public Builder addFieldToIncludeDefaultValue(FieldDescriptor fieldDescriptor) { - this.defaultValueFieldsToPrint.add(fieldDescriptor); - - return this; - } - - /** - * Override implementation of - * {@link TranslationEngine.Builder#addTranslationSpec(TranslationSpec)} that - * also populates the type urls for all Protobuf Message types that exist within - * the translationSpec - * - * @throws ContractException - *
      - *
    • {@link ProtobufCoreTranslationError#INVALID_INPUT_CLASS} - * if the given inputClassRef is not assignable from - * {@linkplain Message} nor - * {@linkplain ProtocolMessageEnum}
    • - *
    • {@link ProtobufCoreTranslationError#INVALID_TRANSLATION_SPEC} - * if the given translation spec is not assignable - * from {@linkplain ProtobufTranslationSpec}
    • - *
    - */ - @Override - public Builder addTranslationSpec(TranslationSpec translationSpec) { - _addTranslationSpec(translationSpec); - - if (!ProtobufTranslationSpec.class.isAssignableFrom(translationSpec.getClass())) { - throw new ContractException(ProtobufCoreTranslationError.INVALID_TRANSLATION_SPEC); - } - - populate(translationSpec.getInputObjectClass()); - return this; - } - - @Override - public Builder addTranslator(Translator translator) { - _addTranslator(translator); - - return this; - } - - @Override - public Builder addParentChildClassRelationship(Class classRef, Class markerInterface) { - _addParentChildClassRelationship(classRef, markerInterface); - - return this; - } - - /** - * checks the class to determine if it is a ProtocolMessageEnum or a Message and - * if so, gets the Descriptor (which is akin to a class but for a Protobuf - * Message) for it to get the full name and add the typeUrl to the internal - * descriptorMap and typeUrlToClassMap - * - * @throws ContractException {@link ProtobufCoreTranslationError#INVALID_INPUT_CLASS} - * if the given inputClassRef is not assignable from - * {@linkplain Message} nor - * {@linkplain ProtocolMessageEnum} - */ - void populate(Class classRef) { - String typeUrl; - if (ProtocolMessageEnum.class.isAssignableFrom(classRef) && ProtocolMessageEnum.class != classRef) { - typeUrl = getDefaultEnum(classRef.asSubclass(ProtocolMessageEnum.class)).getDescriptorForType() - .getFullName(); - this.data.typeUrlToClassMap.putIfAbsent(typeUrl, classRef); - return; - } - - if (Message.class.isAssignableFrom(classRef) && Message.class != classRef) { - Message message = getDefaultMessage(classRef.asSubclass(Message.class)); - typeUrl = message.getDescriptorForType().getFullName(); - - this.data.typeUrlToClassMap.putIfAbsent(typeUrl, classRef); - this.descriptorSet.add(message.getDescriptorForType()); - return; - } - - throw new ContractException(ProtobufCoreTranslationError.INVALID_INPUT_CLASS); - } - - /** - * given a Class ref to a Protobuf Message, get the defaultInstance of it - */ - U getDefaultMessage(Class classRef) { - try { - Method method = classRef.getMethod("getDefaultInstance"); - Object obj = method.invoke(null); - return classRef.cast(obj); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - /** - * given a Class ref to a ProtocolMessageEnum, get the default value for it, - * enum number 0 within the proto enum - */ - U getDefaultEnum(Class classRef) { - try { - Method method = classRef.getMethod("forNumber", int.class); - Object obj = method.invoke(null, 0); - return classRef.cast(obj); - } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException - | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - - } - - /** - * Returns a new builder - */ - public static Builder builder() { - return new Builder(new Data()); - } - - Parser getJsonParser() { - return this.data.jsonParser; - } - - Printer getJsonPrinter() { - return this.data.jsonPrinter; - } - - void setDebug(boolean debug) { - this.debug = debug; - } - - /** - * write output implementation - *

    - * Will first convert the object, if needed and then use the jsonPrinter to take - * the the converted object and write it to a JSON string and then pass that - * string to the writer to writer the JSON to an output file - * - * @param the type of the optional parent class of the appObject - * @param the type of the appObject - * @throws RuntimeException if there is an IOException during writing - */ - protected void writeOutput(Path path, M appObject, Optional> superClass) - throws IOException { - Message message; - if (Message.class.isAssignableFrom(appObject.getClass())) { - message = Message.class.cast(appObject); - } else if (superClass.isPresent()) { - message = convertObjectAsSafeClass(appObject, superClass.get()); - } else { - message = convertObject(appObject); - } - writeOutput(path, message); - } - - /** - * takes a protobuf message, parses it into a JSON string and then writes the - * JSON string to the output file for which the writer is defined. - *

    - * if debug is enabled in this class, it will also print the resulting output to - * the console - *

    - * - * @param the type of the Message - * @throws RuntimeException if there is an IOException during writing - */ - private void writeOutput(Path path, U message) { - try { - BufferedWriter writer = new BufferedWriter(new FileWriter(path.toFile())); - this.data.jsonPrinter.appendTo(message, writer); - - if (debug) { - String messageToWrite = this.data.jsonPrinter.print(message); - printJsonToConsole(messageToWrite); - } - - writer.flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void printJsonToConsole(String jsonString) { - System.out.println(jsonString); - } - - /** - * Given a reader and a classRef, will read the JSON from the reader, parse it - * into a JSON Object, merge the resulting JSON Object into the equivalent - * Protobuf Message and then convert that Protobuf Message to the equivalent - * AppObject - *

    - * if debug is set on this class, will also print the resulting read in Protobuf - * Message to console - *

    - * - * @param the type of the inputClass - * @param the return type - * @throws FileNotFoundException - * @throws RuntimeException - *
      - *
    • if there is an issue getting the builder - * method - * from the inputClassRef
    • - *
    • if there is an issue merging the read in - * JSON - * object into the resulting Protobuf Message - * builder - *
    • - *
    - * @throws ContractException {@linkplain ProtobufCoreTranslationError#INVALID_READ_INPUT_CLASS_REF} - * if the given inputClassRef is not assignable - * from - * {@linkplain Message} - */ - protected T readInput(Path path, Class inputClassRef) throws IOException { - if (!Message.class.isAssignableFrom(inputClassRef)) { - throw new ContractException(ProtobufCoreTranslationError.INVALID_READ_INPUT_CLASS_REF); - } - - return parseJson(new FileReader(path.toFile()), inputClassRef.asSubclass(Message.class)); - } - - /** - * Given a jsonObject and a inputClassRef, creates a builder for the inputClass - * type and then merges the JSON object into the resulting builder - *

    - * if debug is set on this class, will also print the resulting read in Protobuf - * Message to console - *

    - * - * @param the return type - * @param the type of the inputClass, that is a child of {@link Message} - * @throws RuntimeException - *
      - *
    • if there is an issue getting the builder method - * from the inputClassRef
    • - *
    • if there is an issue merging the read in JSON - * object into the resulting Protobuf Message builder - *
    • - *
    - */ - T parseJson(Reader reader, Class inputClassRef) { - - Message.Builder builder = getBuilderForMessage(inputClassRef); - - try { - this.data.jsonParser.merge(reader, builder); - - Message message = builder.build(); - if (debug) { - printJsonToConsole(this.data.jsonPrinter.print(message)); - } - - return convertObject(message); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - Message.Builder getBuilderForMessage(Class messageClass) { - - Method[] messageMethods = messageClass.getDeclaredMethods(); - - List newBuilderMethods = new ArrayList<>(); - for (Method method : messageMethods) { - if (method.getName().equals("newBuilder")) { - newBuilderMethods.add(method); - } - } - - if (newBuilderMethods.isEmpty()) { - throw new RuntimeException("The method \"newBuilder\" does not exist"); - } - - for (Method method : newBuilderMethods) { - if (method.getParameterCount() == 0) { - try { - return (com.google.protobuf.Message.Builder) method.invoke(null); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - throw new RuntimeException(e); - } - } - } - - throw new RuntimeException( - "\"newBuilder\" method exists, but it requires arguments, when it is expected to require 0 arguments"); - } - - /** - * Given an object of type {@link Any}, will convert it to the resulting object - *

    - * Will ultimately use the {@link AnyTranslationSpec} to accomplish this - *

    - * - * @param the return type - */ - public T getObjectFromAny(Any anyValue) { - return convertObject(anyValue); - } - - /** - * Given an object , will convert it to an {@link Any} type - *

    - * Will use the {@link AnyTranslationSpec} to accomplish this - *

    - */ - public Any getAnyFromObject(Object object) { - return convertObjectAsUnsafeClass(object, Any.class); - } - - /** - * Given an object , will convert it to an {@link Any} type - *

    - * This method call differs from {@link #getAnyFromObject(Object)} in that it - * will first convert the object using the safe parent class by calling - * {@link #convertObjectAsSafeClass(Object, Class)} and will then use the - * {@link AnyTranslationSpec} to wrap the resulting converted object in an - * {@link Any} - *

    - * - * @param the parent Class - * @param the object class - * @throws ContractException {@linkplain CoreTranslationError#UNKNOWN_TRANSLATION_SPEC} - * if no translationSpec was provided for the given - * parentClassRef - */ - public Any getAnyFromObjectAsSafeClass(M object, Class parentClassRef) { - U convertedObject = convertObjectAsSafeClass(object, parentClassRef); - - return convertObjectAsUnsafeClass(convertedObject, Any.class); - } - - /** - * Given a typeUrl, returns the associated Protobuf Message type Class, if it - * has been previously provided - * - * @throws ContractException {@linkplain ProtobufCoreTranslationError#UNKNOWN_TYPE_URL} - * if the given type url does not exist. This could be - * because the type url was never provided or the type - * url itself is malformed - */ - public Class getClassFromTypeUrl(String typeUrl) { - if (this.data.typeUrlToClassMap.containsKey(typeUrl)) { - return this.data.typeUrlToClassMap.get(typeUrl); - } - - throw new ContractException(ProtobufCoreTranslationError.UNKNOWN_TYPE_URL, - "Unable to find corresponding class for: " + typeUrl); - } - -} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufTranslationSpec.java deleted file mode 100644 index 20cbe13..0000000 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufTranslationSpec.java +++ /dev/null @@ -1,24 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf; - -import gov.hhs.aspr.ms.taskit.core.TranslationEngine; -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; - -/** - * Abstract implementation of {@link TranslationSpec} that sets the - * {@link TranslationEngine} on the Spec to a {@link ProtobufTranslationEngine} - */ -public abstract class ProtobufTranslationSpec extends TranslationSpec { - protected ProtobufTranslationEngine translationEngine; - - protected ProtobufTranslationSpec() { - } - - /** - * init implementation, sets the translationEngine on this translationSpec. - * calls super.init() to ensure this spec was properly initialized. - */ - public void init(TranslationEngine translationEngine) { - super.init(translationEngine); - this.translationEngine = (ProtobufTranslationEngine) translationEngine; - } -} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/IProtobufTaskitEngineBuilder.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/IProtobufTaskitEngineBuilder.java new file mode 100644 index 0000000..79c1f01 --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/IProtobufTaskitEngineBuilder.java @@ -0,0 +1,10 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import gov.hhs.aspr.ms.taskit.core.engine.ITaskitEngineBuilder; + +/** + * Interface for Protobuf Taskit Engine Builders. + */ +public interface IProtobufTaskitEngineBuilder extends ITaskitEngineBuilder { + +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufJsonTaskitEngine.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufJsonTaskitEngine.java new file mode 100644 index 0000000..6775fde --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufJsonTaskitEngine.java @@ -0,0 +1,341 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import com.google.protobuf.Descriptors.Descriptor; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.Message; +import com.google.protobuf.ProtocolMessageEnum; +import com.google.protobuf.util.JsonFormat; +import com.google.protobuf.util.JsonFormat.Parser; +import com.google.protobuf.util.JsonFormat.Printer; +import com.google.protobuf.util.JsonFormat.TypeRegistry; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineData; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorContext; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslator; +import gov.hhs.aspr.ms.util.errors.ContractException; + +/** + * Protobuf TaskitEngine that reads/writes from/to JSON files into Protobuf + * {@link Message} types + */ +public final class ProtobufJsonTaskitEngine extends ProtobufTaskitEngine { + private final Data data; + + private ProtobufJsonTaskitEngine(Data data, Map> typeUrlToClassMap, + TaskitEngineData taskitEngineData) { + super(typeUrlToClassMap, taskitEngineData, ProtobufTaskitEngineId.JSON_ENGINE_ID); + this.data = data; + } + + private final static class Data { + // these two fields are used for reading and writing Protobuf Messages to/from + // JSON + private Parser jsonParser; + private Printer jsonPrinter; + + private Data() { + } + } + + /** + * Builder for the ProtobufJsonTaskitEngine. + */ + public final static class Builder implements IProtobufTaskitEngineBuilder { + private Data data; + private Set descriptorSet = new LinkedHashSet<>(); + private final Set defaultValueFieldsToPrint = new LinkedHashSet<>(); + private boolean ignoringUnknownFields = true; + private boolean includingDefaultValueFields = false; + + // this is used specifically for Any message types to pack and unpack them + private final Map> typeUrlToClassMap = new LinkedHashMap<>(); + + private TaskitEngineData.Builder taskitEngineDataBuilder = TaskitEngineData.builder(); + + private Builder(ProtobufJsonTaskitEngine.Data data) { + this.data = data; + } + + /** + * Returns a new instance of a ProtobufTaskitEngine that has a jsonParser and + * jsonWriter that include all the typeUrls for all added TranslationSpecs and + * their respective Protobuf Message types. + * + * @throws ContractException + *
      + *
    • {@link TaskitError#UNINITIALIZED_TRANSLATORS} + * if translators were added to the engine but their + * initialized flag was still set to false
    • + *
    • {@link TaskitError#DUPLICATE_TRANSLATOR} if a + * duplicate translator is found
    • + *
    • {@link TaskitError#MISSING_TRANSLATOR} if an + * added translator has a unmet dependency
    • + *
    • {@link TaskitError#CIRCULAR_TRANSLATOR_DEPENDENCIES} + * if the added translators have a circular dependency + * graph
    • + *
    • {@link TaskitError#NO_TRANSLATION_SPECS} if no + * translation specs were added to the engine
    • + *
    + */ + public ProtobufJsonTaskitEngine build() { + + this.addTranslator(ProtobufTranslator.getTranslator()); + + TypeRegistry.Builder typeRegistryBuilder = TypeRegistry.newBuilder(); + + this.descriptorSet.forEach((descriptor) -> { + typeRegistryBuilder.add(descriptor); + }); + + TypeRegistry registry = typeRegistryBuilder.build(); + + Parser parser = JsonFormat.parser().usingTypeRegistry(registry); + + if (this.ignoringUnknownFields) { + parser = parser.ignoringUnknownFields(); + } + + this.data.jsonParser = parser; + + Printer printer = JsonFormat.printer().usingTypeRegistry(registry); + + if (!this.defaultValueFieldsToPrint.isEmpty()) { + printer = printer.includingDefaultValueFields(this.defaultValueFieldsToPrint); + } + + if (this.includingDefaultValueFields) { + printer = printer.includingDefaultValueFields(); + } + + this.data.jsonPrinter = printer; + + ProtobufJsonTaskitEngine protoJsonTaskitEngine = new ProtobufJsonTaskitEngine(this.data, + this.typeUrlToClassMap, this.taskitEngineDataBuilder.build()); + + protoJsonTaskitEngine.init(); + + return protoJsonTaskitEngine; + } + + /** + * Sets the flag indicating whether the jsonParser should ignore fields in the + * JSON file that don't exist in the associated Proto Message. + *

    + * Defaults to true. + *

    + * + * @param ignoringUnknownFields the flag + * @return the builder instance + */ + public Builder setIgnoringUnknownFields(boolean ignoringUnknownFields) { + this.ignoringUnknownFields = ignoringUnknownFields; + return this; + } + + /** + * Sets the flag indicating whether the jsonWrite should print all default + * values. + *

    + * The default values can be found here: + * https://protobuf.dev/programming-guides/proto3/#default + *

    + * Defaults to false. + *

    + * + * @param includingDefaultValueFields the flag + * @return the builder instance + */ + public Builder setIncludingDefaultValueFields(boolean includingDefaultValueFields) { + this.includingDefaultValueFields = includingDefaultValueFields; + return this; + } + + /** + * Contrary to {@link Builder#setIncludingDefaultValueFields(boolean)} which + * will set the flag globally for all default values, this will set the flag for + * a specific default field. + *

    + * All fields default to false. + *

    + * + * @param fieldDescriptor the descriptor of the field to print the default value + * for + * @return the builder instance + * + * @throws ContractException {@link ProtobufTaskitError#NULL_FIELD_DESCRIPTOR} + * if the provided field descriptor is null + */ + public Builder addFieldToIncludeDefaultValue(FieldDescriptor fieldDescriptor) { + if (fieldDescriptor == null) { + throw new ContractException(ProtobufTaskitError.NULL_FIELD_DESCRIPTOR); + } + + this.defaultValueFieldsToPrint.add(fieldDescriptor); + + return this; + } + + /** + * Adds the given {@link ITranslationSpec} to the TaskitEngine. + *

    + * Additionally will populate typeUrls and field descriptors associated with the + * Protobuf types on the given TranslationSpec. + *

    + * + * @throws ContractException + *
      + *
    • {@linkplain TaskitError#NULL_TRANSLATION_SPEC} + * if the given translationSpec is null
    • + *
    • {@linkplain TaskitError#NULL_TRANSLATION_SPEC_CLASS_MAP} + * if the given translationSpec's class map is + * null
    • + *
    • {@linkplain TaskitError#EMPTY_TRANSLATION_SPEC_CLASS_MAP} + * if the given translationSpec's class map is + * empty
    • + *
    • {@linkplain TaskitError#DUPLICATE_TRANSLATION_SPEC} + * if the given translationSpec is already known
    • + *
    • {@link ProtobufTaskitError#INVALID_TRANSLATION_SPEC} + * if the given translation spec is not assignable + * from {@linkplain ProtobufTranslationSpec}
    • + *
    • {@link ProtobufTaskitError#INVALID_TRANSLATION_SPEC_INPUT_CLASS} + * if the given inputClassRef is not assignable from + * {@linkplain Message} nor + * {@linkplain ProtocolMessageEnum}
    • + *
    + */ + @Override + public Builder addTranslationSpec(ITranslationSpec translationSpec) { + this.taskitEngineDataBuilder.addTranslationSpec(translationSpec); + + if (!ProtobufTranslationSpec.class.isAssignableFrom(translationSpec.getClass())) { + throw new ContractException(ProtobufTaskitError.INVALID_TRANSLATION_SPEC); + } + + ProtobufTranslationSpec protobufTranslationSpec = ProtobufTranslationSpec.class.cast(translationSpec); + + populate(protobufTranslationSpec.getInputObjectClass()); + return this; + } + + /** + * Adds a {@link Translator}. + * + * @throws ContractException {@linkplain TaskitError#NULL_TRANSLATOR} if + * translator is null + */ + @Override + public Builder addTranslator(Translator translator) { + this.taskitEngineDataBuilder.addTranslator(translator); + + translator.initialize(new TranslatorContext(this)); + + return this; + } + + /** + * Checks the class to determine if it is a ProtocolMessageEnum or a Message. + *

    + * If it is a Message, gets the Descriptor (which is akin to a class but for a + * Protobuf + * Message) for it to get the full name and add the typeUrl to the internal + * descriptorMap and typeUrlToClassMap. + *

    + *

    + * Package access for testing. + *

    + * + * @param the type of the classRef + * @param classRef the classRef to use + * + * @throws ContractException {@link ProtobufTaskitError#INVALID_TRANSLATION_SPEC_INPUT_CLASS} + * if the given inputClassRef is not assignable from + * {@linkplain Message} nor + * {@linkplain ProtocolMessageEnum} + * + * @throws RuntimeException if there is any issue using reflection to invoke + * either the 'getDefaultInstance' method on a + * {@link Message} type or invoking the 'forNumber(0)' + * method on the {@link ProtocolMessageEnum} type + */ + void populate(Class classRef) { + String typeUrl; + if (ProtocolMessageEnum.class.isAssignableFrom(classRef) && ProtocolMessageEnum.class != classRef) { + typeUrl = ProtobufTaskitEngineHelper.getDefaultEnum(classRef.asSubclass(ProtocolMessageEnum.class)) + .getDescriptorForType().getFullName(); + this.typeUrlToClassMap.putIfAbsent(typeUrl, classRef); + return; + } + + if (Message.class.isAssignableFrom(classRef) && Message.class != classRef) { + Message message = ProtobufTaskitEngineHelper.getDefaultMessage(classRef.asSubclass(Message.class)); + typeUrl = message.getDescriptorForType().getFullName(); + + this.typeUrlToClassMap.putIfAbsent(typeUrl, classRef); + this.descriptorSet.add(message.getDescriptorForType()); + return; + } + + throw new ContractException(ProtobufTaskitError.INVALID_TRANSLATION_SPEC_INPUT_CLASS); + } + + } + + /** + * Returns a new builder for the Protobuf Json Taskit engine. + */ + public static Builder builder() { + return new Builder(new Data()); + } + + /** + * Package access for testing. + * + * @return the JSONParser instance for this engine + */ + Parser getJsonParser() { + return this.data.jsonParser; + } + + /** + * Package access for testing. + * + * @return the JSONPrinter instance for this engine + */ + Printer getJsonPrinter() { + return this.data.jsonPrinter; + } + + @Override + protected void writeToFile(File file, Message message) throws IOException { + BufferedWriter writer = new BufferedWriter(new FileWriter(file)); + this.data.jsonPrinter.appendTo(message, writer); + + writer.flush(); + } + + @Override + protected Message readFile(File file, Message.Builder builder) throws IOException { + Reader buffReader = new BufferedReader(new FileReader(file)); + + this.data.jsonParser.merge(buffReader, builder); + + return builder.build(); + } + +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngine.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngine.java new file mode 100644 index 0000000..d41f689 --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngine.java @@ -0,0 +1,201 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import java.io.File; +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.Map; + +import com.google.protobuf.Any; +import com.google.protobuf.Message; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineData; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineId; +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.AnyTranslationSpec; +import gov.hhs.aspr.ms.util.errors.ContractException; + +/** + * Abstract ProtobufTaskitEngine that defines the common methods that are shared + * between a JSON engine and a Binary Engine + */ +public abstract class ProtobufTaskitEngine extends TaskitEngine { + + // this is used specifically for Any message types to pack and unpack them + protected final Map> typeUrlToClassMap = new LinkedHashMap<>(); + + protected ProtobufTaskitEngine(Map> typeUrlToClassMap, TaskitEngineData taskitEngineData, + TaskitEngineId taskitEngineId) { + super(taskitEngineData, taskitEngineId); + this.typeUrlToClassMap.putAll(typeUrlToClassMap); + + } + + @Override + protected final void writeToFile(File file, O outputObject) throws IOException { + if (!Message.class.isAssignableFrom(outputObject.getClass())) { + throw new ContractException(TaskitError.INVALID_OUTPUT_CLASS, Message.class.getName()); + } + + this.writeToFile(file, Message.class.cast(outputObject)); + } + + @Override + protected final I readFile(File file, Class inputClassRef) throws IOException { + if (!Message.class.isAssignableFrom(inputClassRef)) { + throw new ContractException(TaskitError.INVALID_INPUT_CLASS, Message.class.getName()); + } + + Message.Builder builder = ProtobufTaskitEngineHelper + .getBuilderForMessage(inputClassRef.asSubclass(Message.class)); + + Message message = this.readFile(file, builder); + + return inputClassRef.cast(message); + } + + protected abstract void writeToFile(File file, Message message) throws IOException; + + protected abstract Message readFile(File file, Message.Builder builder) throws IOException; + + /** + * Translate a object of type {@link Any} to the wrapped object's corresponding + * app type + *

    + * this will call {@link AnyTranslationSpec#translate(Object)} via + * {@link #translateObject(Object)} + * + * @param the object type + * @param anyValue the any value to get an object from + * @return the object that was wrapped in the any + * + * @throws ContractException + *

      + *
    • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
    • + *
    + */ + public final T getObjectFromAny(Any anyValue) { + return this.translateObject(anyValue); + } + + /** + * Translate an Object into a {@link Any} type + *

    + * this will call {@link AnyTranslationSpec#translate(Object)} via + * {@link #translateObjectAsClassUnsafe(Object, Class)} + * + * @param object the object to translate + * @return the resulting Any + * + * @throws ContractException + *

      + *
    • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
    • + *
    + */ + public final Any getAnyFromObject(Object object) { + return this.translateObjectAsClassUnsafe(object, Any.class); + } + + /** + * Translate an object into an {@link Any} type + *

    + * This method call differs from {@link #getAnyFromObject(Object)} in that it + * will first translate the object using the classRef by calling + * {@link #translateObjectAsClassSafe(Object, Class)} and will then call + * {@link #translateObjectAsClassUnsafe(Object, Class)} to translate the + * translated object into an {@link Any} type using + * {@link AnyTranslationSpec#translate(Object)} + *

    + * + * @param the type of the object + * @param the type to translate the object as + * @param object the object to translate + * @param classRef the classRef of the type to translate the object as + * @return the translated object wrapped into an Any type + * + * @throws ContractException + *
      + *
    • {@linkplain TaskitError#NULL_OBJECT_FOR_TRANSLATION} + * if the passed in object is null
    • + *
    • {@linkplain TaskitError#NULL_CLASS_REF} + * if the passed in classRef is null
    • + *
    • {@linkplain TaskitError#UNKNOWN_TRANSLATION_SPEC} + * if no translationSpec was provided for the given + * objects class
    • + *
    + */ + public final Any getAnyFromObjectAsClassSafe(O object, Class classRef) { + C translatedObject = translateObjectAsClassSafe(object, classRef); + + return this.translateObjectAsClassUnsafe(translatedObject, Any.class); + } + + /** + * Obtain a classRef from a given typeUrl + * + * @param typeUrl the typeUrl to use to obtain a classRef for + * @return the classRef associated with the given typeUrl + * @throws ContractException {@linkplain ProtobufTaskitError#UNKNOWN_TYPE_URL} + * if the given type url does not exist. + *

    + * This could be + * because the type url was never provided or the type + * url itself is malformed + */ + public final Class getClassFromTypeUrl(String typeUrl) { + if (this.typeUrlToClassMap.containsKey(typeUrl)) { + return this.typeUrlToClassMap.get(typeUrl); + } + + throw new ContractException(ProtobufTaskitError.UNKNOWN_TYPE_URL, + "Unable to find corresponding class for: " + typeUrl); + } + + @Override + public int hashCode() { + /* + * Note that we don't include the type url map as part of the hash code contract + * because it is + * directly linked to the added translationSpecs, which are already part of the + * hash code contract. + * Meaning that if the specs are the same, so is the map. There is never a case + * where the map would be different outside of the specs being different. + * However, child classes of this class are free to use the type url map as part + * of their hash code contract if they so wish. + */ + return super.hashCode(); + } + + @Override + public boolean equals(Object obj) { + /* + * Note that we don't include the type url map as part of the equals contract + * because it is + * directly linked to the added translationSpecs, which are already part of the + * equals contract. + * Meaning that if the specs are the same, so is the map. There is never a case + * where the map would be different outside of the specs being different. + * However, child classes of this class are free to use the type url map as part + * of their equals contract if they so wish. + */ + if (this == obj) { + return true; + } + + if (obj == null) { + return false; + } + + if (!(obj instanceof ProtobufTaskitEngine)) { + return false; + } + + if (!super.equals(obj)) { + return false; + } + return true; + } + +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngineHelper.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngineHelper.java new file mode 100644 index 0000000..8d5e176 --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngineHelper.java @@ -0,0 +1,92 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; + +import com.google.protobuf.Message; +import com.google.protobuf.ProtocolMessageEnum; + +/** + * This is a helper class that helps a ProtobufTaskitEngine with various utility + * operations. + *

    + * Package access for testing. + *

    + */ +final class ProtobufTaskitEngineHelper { + private ProtobufTaskitEngineHelper() { + } + + /** + * Returns the Protobuf Message defaultInstance for the given a Class reference. + *

    + * Package access for testing and use in ProtobufTaskitEngines. + *

    + */ + static U getDefaultMessage(Class classRef) { + try { + Method method = classRef.getMethod("getDefaultInstance"); + Object obj = method.invoke(null); + return classRef.cast(obj); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + /** + * Returns the ProtocolMessageEnum defaultInstance(enum number 0 within the + * proto enum) for the given a Class reference. + * + *

    + * Package access for testing and use in ProtobufTaskitEngines. + *

    + */ + static U getDefaultEnum(Class classRef) { + try { + Method method = classRef.getMethod("forNumber", int.class); + Object obj = method.invoke(null, 0); + return classRef.cast(obj); + } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + /** + * Uses reflection to obtain a builder for the given classRef + *

    + * Package access for testing and use in ProtobufTaskitEngines. + *

    + */ + static Message.Builder getBuilderForMessage(Class classRef) { + + Method[] messageMethods = classRef.getDeclaredMethods(); + + List newBuilderMethods = new ArrayList<>(); + for (Method method : messageMethods) { + if (method.getName().equals("newBuilder")) { + newBuilderMethods.add(method); + } + } + + if (newBuilderMethods.isEmpty()) { + throw new RuntimeException("The method \"newBuilder\" does not exist"); + } + + for (Method method : newBuilderMethods) { + if (method.getParameterCount() == 0) { + try { + return (com.google.protobuf.Message.Builder) method.invoke(null); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + } + + throw new RuntimeException( + "\"newBuilder\" method exists, but it requires arguments, when it is expected to require 0 arguments"); + } +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngineId.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngineId.java new file mode 100644 index 0000000..c4aee56 --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitEngineId.java @@ -0,0 +1,14 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngineId; + +/** + * TaskitEngineIds for the JSON and Binary ProtobufTaskitEngines. + */ +public final class ProtobufTaskitEngineId implements TaskitEngineId { + public static final TaskitEngineId JSON_ENGINE_ID = new ProtobufTaskitEngineId(); + public static final TaskitEngineId BINARY_ENGINE_ID = new ProtobufTaskitEngineId(); + + private ProtobufTaskitEngineId() { + } +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufCoreTranslationError.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitError.java similarity index 50% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufCoreTranslationError.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitError.java index cf684bc..47cf755 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/ProtobufCoreTranslationError.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/engine/ProtobufTaskitError.java @@ -1,17 +1,21 @@ -package gov.hhs.aspr.ms.taskit.protobuf; +package gov.hhs.aspr.ms.taskit.protobuf.engine; import gov.hhs.aspr.ms.util.errors.ContractError; -public enum ProtobufCoreTranslationError implements ContractError { - INVALID_INPUT_CLASS("The input class is neither a Protobuf Message, nor a Protobuf Enum"), - INVALID_READ_INPUT_CLASS_REF("The inputClassRef is not of the parent type: Message.class"), +/** + * Contract Exception Errors exclusive to ProtobufTaskit. + */ +public enum ProtobufTaskitError implements ContractError { + INVALID_TRANSLATION_SPEC_INPUT_CLASS("The input class is neither a Protobuf Message, nor a Protobuf Enum"), + INVALID_INPUT_CLASS("The inputClassRef is not of the parent type: Message.class"), INVALID_TRANSLATION_SPEC("Added Translation Specs need to be of parent type Protobuf TranslationSpecs"), + NULL_FIELD_DESCRIPTOR("The provided field descriptor is null"), UNKNOWN_TYPE_URL( "The given type url does not have a corresponding classRef. Either the typeUrl was never provided, or the typeUrl is malformed."); private final String description; - private ProtobufCoreTranslationError(final String description) { + private ProtobufTaskitError(final String description) { this.description = description; } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/TestProtobufEnumTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/TestProtobufEnumTranslationSpec.java deleted file mode 100644 index 2151993..0000000 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/TestProtobufEnumTranslationSpec.java +++ /dev/null @@ -1,27 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs; - -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppEnum; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputEnum; - -public class TestProtobufEnumTranslationSpec extends ProtobufTranslationSpec { - @Override - protected TestAppEnum convertInputObject(TestInputEnum inputObject) { - return TestAppEnum.valueOf(inputObject.name()); - } - - @Override - protected TestInputEnum convertAppObject(TestAppEnum appObject) { - return TestInputEnum.valueOf(appObject.name()); - } - - @Override - public Class getAppObjectClass() { - return TestAppEnum.class; - } - - @Override - public Class getInputObjectClass() { - return TestInputEnum.class; - } -} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject/translationSpecs/TestProtobufComplexObjectTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufComplexObjectTranslationSpec.java similarity index 63% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject/translationSpecs/TestProtobufComplexObjectTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufComplexObjectTranslationSpec.java index 03a126b..ed39251 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject/translationSpecs/TestProtobufComplexObjectTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufComplexObjectTranslationSpec.java @@ -1,14 +1,17 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.input.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; +/** + * Translation spec implementation for the TestComplexObject. + */ public class TestProtobufComplexObjectTranslationSpec extends ProtobufTranslationSpec { @Override - protected TestComplexAppObject convertInputObject(TestComplexInputObject inputObject) { + protected TestComplexAppObject translateInputObject(TestComplexInputObject inputObject) { TestComplexAppObject testComplexAppObject = new TestComplexAppObject(); testComplexAppObject.setNumEntities(inputObject.getNumEntities()); @@ -19,7 +22,7 @@ protected TestComplexAppObject convertInputObject(TestComplexInputObject inputOb } @Override - protected TestComplexInputObject convertAppObject(TestComplexAppObject appObject) { + protected TestComplexInputObject translateAppObject(TestComplexAppObject appObject) { return TestComplexInputObject.newBuilder().setNumEntities(appObject.getNumEntities()) .setStartTime(appObject.getStartTime()).setTestString(appObject.getTestString()).build(); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufEnumTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufEnumTranslationSpec.java new file mode 100644 index 0000000..141c6fa --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufEnumTranslationSpec.java @@ -0,0 +1,31 @@ +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs; + +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppEnum; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputEnum; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; + +/** + * Translation Spec implementation for TestEnum. + */ +public class TestProtobufEnumTranslationSpec extends ProtobufTranslationSpec { + + @Override + protected TestAppEnum translateInputObject(TestInputEnum inputObject) { + return TestAppEnum.valueOf(inputObject.name()); + } + + @Override + protected TestInputEnum translateAppObject(TestAppEnum appObject) { + return TestInputEnum.valueOf(appObject.name()); + } + + @Override + public Class getAppObjectClass() { + return TestAppEnum.class; + } + + @Override + public Class getInputObjectClass() { + return TestInputEnum.class; + } +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/TestProtobufObjectTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufObjectTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/TestProtobufObjectTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufObjectTranslationSpec.java index 9735d5b..07a8a26 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/TestProtobufObjectTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/TestProtobufObjectTranslationSpec.java @@ -1,30 +1,34 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; +/** + * Translation Spec implementation for TestObject. + */ public class TestProtobufObjectTranslationSpec extends ProtobufTranslationSpec { + @Override - protected TestAppObject convertInputObject(TestInputObject inputObject) { + protected TestAppObject translateInputObject(TestInputObject inputObject) { TestAppObject testAppObject = new TestAppObject(); testAppObject.setBool(inputObject.getBool()); testAppObject.setInteger(inputObject.getInteger()); testAppObject.setString(inputObject.getString()); testAppObject - .setTestComplexAppObject(this.translationEngine.convertObject(inputObject.getTestComplexInputObject())); + .setTestComplexAppObject(this.taskitEngine.translateObject(inputObject.getTestComplexInputObject())); return testAppObject; } @Override - protected TestInputObject convertAppObject(TestAppObject appObject) { + protected TestInputObject translateAppObject(TestAppObject appObject) { TestInputObject testInputObject = TestInputObject.newBuilder().setBool(appObject.isBool()) .setInteger(appObject.getInteger()).setString(appObject.getString()) - .setTestComplexInputObject((TestComplexInputObject) this.translationEngine - .convertObject(appObject.getTestComplexAppObject())) + .setTestComplexInputObject((TestComplexInputObject) this.taskitEngine + .translateObject(appObject.getTestComplexAppObject())) .build(); return testInputObject; diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslationSpec.java new file mode 100644 index 0000000..aa73bef --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslationSpec.java @@ -0,0 +1,17 @@ +package gov.hhs.aspr.ms.taskit.protobuf.translation; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitEngine; +import gov.hhs.aspr.ms.taskit.core.translation.TranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufTaskitEngine; + +/** + * Abstract implementation of {@link TranslationSpec} that sets the + * {@link TaskitEngine} on the Spec to a {@link ProtobufTaskitEngine}. + */ +public abstract class ProtobufTranslationSpec extends TranslationSpec { + + protected ProtobufTranslationSpec() { + super(ProtobufTaskitEngine.class); + } + +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslator.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslator.java new file mode 100644 index 0000000..3d1cace --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslator.java @@ -0,0 +1,72 @@ +package gov.hhs.aspr.ms.taskit.protobuf.translation; + +import java.util.ArrayList; +import java.util.List; + +import com.google.protobuf.Any; + +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.protobuf.engine.IProtobufTaskitEngineBuilder; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufTaskitEngine; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.AnyTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.BooleanTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.DateTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.DoubleTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.EnumTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.FloatTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.IntegerTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.LongTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.StringTranslationSpec; + +/** + * Translator for the primitive Protobuf Translation Specs + *

    + * this is added to every {@link ProtobufTaskitEngine} and the specs are + * specifically used in conjunction with the {@link Any} type. + *

    + */ +public class ProtobufTranslator { + private ProtobufTranslator() { + } + + protected static List getTranslationSpecs() { + List list = new ArrayList<>(); + + list.add(new BooleanTranslationSpec()); + list.add(new IntegerTranslationSpec()); + list.add(new LongTranslationSpec()); + list.add(new StringTranslationSpec()); + list.add(new FloatTranslationSpec()); + list.add(new DoubleTranslationSpec()); + list.add(new DateTranslationSpec()); + list.add(new EnumTranslationSpec()); + list.add(new AnyTranslationSpec()); + + return list; + } + + private static Translator.Builder builder() { + Translator.Builder builder = Translator.builder() + .setTranslatorId(ProtobufTranslatorId.TRANSLATOR_ID) + .setInitializer((translatorContext) -> { + IProtobufTaskitEngineBuilder translationEngineBuilder = translatorContext + .getTaskitEngineBuilder(IProtobufTaskitEngineBuilder.class); + + for (ITranslationSpec translationSpec : getTranslationSpecs()) { + translationEngineBuilder.addTranslationSpec(translationSpec); + } + + }); + + return builder; + } + + /** + * Returns a Translator that includes primitive TranslationSpecs for the + * ProtobufTaskitEngine that are used for packing/unpacking {@link Any}s + */ + public static Translator getTranslator() { + return builder().build(); + } +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslatorId.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslatorId.java new file mode 100644 index 0000000..879fa0a --- /dev/null +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/ProtobufTranslatorId.java @@ -0,0 +1,13 @@ +package gov.hhs.aspr.ms.taskit.protobuf.translation; + +import gov.hhs.aspr.ms.taskit.core.translation.TranslatorId; + +/** + * Identifier for the Protobuf Translator. + */ +public class ProtobufTranslatorId implements TranslatorId { + public final static TranslatorId TRANSLATOR_ID = new ProtobufTranslatorId(); + + private ProtobufTranslatorId() { + } +} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AnyTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AnyTranslationSpec.java similarity index 69% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AnyTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AnyTranslationSpec.java index 71f107d..c7c7288 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AnyTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AnyTranslationSpec.java @@ -1,19 +1,19 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.Any; import com.google.protobuf.InvalidProtocolBufferException; import com.google.protobuf.Message; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Object to a - * Protobuf {@link Any} type and vice versa + * TranslationSpec that defines how to translate from any Java Object to a + * Protobuf {@link Any} type and vice versa. */ public class AnyTranslationSpec extends ProtobufTranslationSpec { @Override - protected Object convertInputObject(Any inputObject) { + protected Object translateInputObject(Any inputObject) { String fullTypeUrl = inputObject.getTypeUrl(); String[] parts = fullTypeUrl.split("/"); @@ -22,7 +22,7 @@ protected Object convertInputObject(Any inputObject) { } String typeUrl = parts[1]; - Class classRef = this.translationEngine.getClassFromTypeUrl(typeUrl); + Class classRef = this.taskitEngine.getClassFromTypeUrl(typeUrl); Class messageClassRef; if (!(Message.class.isAssignableFrom(classRef))) { @@ -38,27 +38,27 @@ protected Object unpackMessage(Any inputObject, Class mes try { Message unpackedMessage = inputObject.unpack(messageClassRef); - return this.translationEngine.convertObject(unpackedMessage); + return this.taskitEngine.translateObject(unpackedMessage); } catch (InvalidProtocolBufferException e) { throw new RuntimeException("Unable To unpack any type to given class: " + messageClassRef.getName(), e); } } @Override - protected Any convertAppObject(Object appObject) { + protected Any translateAppObject(Object appObject) { Message message; if (Enum.class.isAssignableFrom(appObject.getClass())) { - message = this.translationEngine.convertObjectAsSafeClass(Enum.class.cast(appObject), Enum.class); + message = this.taskitEngine.translateObjectAsClassSafe(Enum.class.cast(appObject), Enum.class); } - // in the event that the object was converted BEFORE calling this + // in the event that the object was translated BEFORE calling this // translationSpec, there is no need to translate it again. else if (Message.class.isAssignableFrom(appObject.getClass())) { message = Message.class.cast(appObject); } else { - message = this.translationEngine.convertObject(appObject); + message = this.taskitEngine.translateObject(appObject); } return Any.pack(message); diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/BooleanTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/BooleanTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/BooleanTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/BooleanTranslationSpec.java index 4fb7716..62c1f0e 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/BooleanTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/BooleanTranslationSpec.java @@ -1,22 +1,22 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.BoolValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Boolean to a - * Protobuf {@link BoolValue} type and vice versa + * TranslationSpec that defines how to translate from any Java Boolean to a + * Protobuf {@link BoolValue} type and vice versa. */ public class BooleanTranslationSpec extends ProtobufTranslationSpec { @Override - protected Boolean convertInputObject(BoolValue inputObject) { + protected Boolean translateInputObject(BoolValue inputObject) { return inputObject.getValue(); } @Override - protected BoolValue convertAppObject(Boolean appObject) { + protected BoolValue translateAppObject(Boolean appObject) { return BoolValue.of(appObject); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/DateTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/DateTranslationSpec.java similarity index 62% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/DateTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/DateTranslationSpec.java index 96adb84..1e83cb9 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/DateTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/DateTranslationSpec.java @@ -1,24 +1,24 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import java.time.LocalDate; import com.google.type.Date; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java {@link LocalDate} - * to a Protobuf {@link Date} type and vice versa + * TranslationSpec that defines how to translate from any Java {@link LocalDate} + * to a Protobuf {@link Date} type and vice versa. */ public class DateTranslationSpec extends ProtobufTranslationSpec { @Override - protected LocalDate convertInputObject(Date inputObject) { + protected LocalDate translateInputObject(Date inputObject) { return LocalDate.of(inputObject.getYear(), inputObject.getMonth(), inputObject.getDay()); } @Override - protected Date convertAppObject(LocalDate appObject) { + protected Date translateAppObject(LocalDate appObject) { return Date.newBuilder().setYear(appObject.getYear()).setMonth(appObject.getMonth().getValue()) .setDay(appObject.getDayOfMonth()).build(); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/DoubleTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/DoubleTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/DoubleTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/DoubleTranslationSpec.java index 60b82d4..97214d8 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/DoubleTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/DoubleTranslationSpec.java @@ -1,22 +1,22 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.DoubleValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Double to a - * Protobuf {@link DoubleValue} type and vice versa + * TranslationSpec that defines how to translate from any Java Double to a + * Protobuf {@link DoubleValue} type and vice versa. */ public class DoubleTranslationSpec extends ProtobufTranslationSpec { @Override - protected Double convertInputObject(DoubleValue inputObject) { + protected Double translateInputObject(DoubleValue inputObject) { return inputObject.getValue(); } @Override - protected DoubleValue convertAppObject(Double appObject) { + protected DoubleValue translateAppObject(Double appObject) { return DoubleValue.of(appObject); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/EnumTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/EnumTranslationSpec.java similarity index 64% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/EnumTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/EnumTranslationSpec.java index b05e0a9..91ac962 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/EnumTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/EnumTranslationSpec.java @@ -1,38 +1,38 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import java.lang.reflect.InvocationTargetException; import com.google.protobuf.Any; import com.google.protobuf.ProtocolMessageEnum; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.input.WrapperEnumValue; +import gov.hhs.aspr.ms.taskit.protobuf.objects.WrapperEnumValue; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Enum to a Protobuf - * {@link WrapperEnumValue} type and vice versa + * TranslationSpec that defines how to translate from any Java Enum to a Protobuf + * {@link WrapperEnumValue} type and vice versa. *

    * Note: A {@link WrapperEnumValue} is specifically used to wrap a Enum into - * a Protobuf {@link Any} type + * a Protobuf {@link Any} type. *

    *

    * The Protobuf {@link Any} type does not natively support enums, only - * primitives and other Protobuf Messages + * primitives and other Protobuf Messages. *

    */ @SuppressWarnings("rawtypes") public class EnumTranslationSpec extends ProtobufTranslationSpec { @Override - protected Enum convertInputObject(WrapperEnumValue inputObject) { + protected Enum translateInputObject(WrapperEnumValue inputObject) { String typeUrl = inputObject.getEnumTypeUrl(); String value = inputObject.getValue(); - Class classRef = this.translationEngine.getClassFromTypeUrl(typeUrl); + Class classRef = this.taskitEngine.getClassFromTypeUrl(typeUrl); try { Enum inputInput = (Enum) classRef.getMethod("valueOf", String.class).invoke(null, value); - return this.translationEngine.convertObject(inputInput); + return this.taskitEngine.translateObject(inputInput); } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { throw new RuntimeException(e); @@ -41,8 +41,8 @@ protected Enum convertInputObject(WrapperEnumValue inputObject) { } @Override - protected WrapperEnumValue convertAppObject(Enum appObject) { - ProtocolMessageEnum messageEnum = this.translationEngine.convertObject(appObject); + protected WrapperEnumValue translateAppObject(Enum appObject) { + ProtocolMessageEnum messageEnum = this.taskitEngine.translateObject(appObject); WrapperEnumValue wrapperEnumValue = WrapperEnumValue.newBuilder() .setValue(messageEnum.getValueDescriptor().getName()) diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/FloatTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/FloatTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/FloatTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/FloatTranslationSpec.java index a84f230..6f226a2 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/FloatTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/FloatTranslationSpec.java @@ -1,22 +1,22 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.FloatValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Float to a Protobuf - * {@link FloatValue} type and vice versa + * TranslationSpec that defines how to translate from any Java Float to a Protobuf + * {@link FloatValue} type and vice versa. */ public class FloatTranslationSpec extends ProtobufTranslationSpec { @Override - protected Float convertInputObject(FloatValue inputObject) { + protected Float translateInputObject(FloatValue inputObject) { return inputObject.getValue(); } @Override - protected FloatValue convertAppObject(Float appObject) { + protected FloatValue translateAppObject(Float appObject) { return FloatValue.of(appObject); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/IntegerTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/IntegerTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/IntegerTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/IntegerTranslationSpec.java index ada7023..cb10e56 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/IntegerTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/IntegerTranslationSpec.java @@ -1,22 +1,22 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.Int32Value; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Integer to a - * Protobuf {@link Int32Value} type and vice versa + * TranslationSpec that defines how to translate from any Java Integer to a + * Protobuf {@link Int32Value} type and vice versa. */ public class IntegerTranslationSpec extends ProtobufTranslationSpec { @Override - protected Integer convertInputObject(Int32Value inputObject) { + protected Integer translateInputObject(Int32Value inputObject) { return inputObject.getValue(); } @Override - protected Int32Value convertAppObject(Integer appObject) { + protected Int32Value translateAppObject(Integer appObject) { return Int32Value.of(appObject); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/LongTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/LongTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/LongTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/LongTranslationSpec.java index a9974d1..b67c34e 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/LongTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/LongTranslationSpec.java @@ -1,22 +1,22 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.Int64Value; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java Long to a Protobuf - * {@link Int64Value} type and vice versa + * TranslationSpec that defines how to translate from any Java Long to a Protobuf + * {@link Int64Value} type and vice versa. */ public class LongTranslationSpec extends ProtobufTranslationSpec { @Override - protected Long convertInputObject(Int64Value inputObject) { + protected Long translateInputObject(Int64Value inputObject) { return inputObject.getValue(); } @Override - protected Int64Value convertAppObject(Long appObject) { + protected Int64Value translateAppObject(Long appObject) { return Int64Value.of(appObject); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/StringTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/StringTranslationSpec.java similarity index 54% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/StringTranslationSpec.java rename to protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/StringTranslationSpec.java index 9559ef9..8f06d83 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/StringTranslationSpec.java +++ b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/StringTranslationSpec.java @@ -1,22 +1,22 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import com.google.protobuf.StringValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; /** - * TranslationSpec that defines how to convert from any Java String to a - * Protobuf {@link StringValue} type and vice versa + * TranslationSpec that defines how to translate from any Java String to a + * Protobuf {@link StringValue} type and vice versa. */ public class StringTranslationSpec extends ProtobufTranslationSpec { @Override - protected String convertInputObject(StringValue inputObject) { + protected String translateInputObject(StringValue inputObject) { return inputObject.getValue(); } @Override - protected StringValue convertAppObject(String appObject) { + protected StringValue translateAppObject(String appObject) { return StringValue.of(appObject); } diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/UIntegerTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/UIntegerTranslationSpec.java deleted file mode 100644 index 0b4f7d2..0000000 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/UIntegerTranslationSpec.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; - -import com.google.protobuf.UInt32Value; - -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; - -/** - * TranslationSpec that defines how to convert from any Java Integer to a - * Protobuf {@link UInt32Value} type and vice versa - */ -public class UIntegerTranslationSpec extends ProtobufTranslationSpec { - - @Override - protected Integer convertInputObject(UInt32Value inputObject) { - return inputObject.getValue(); - } - - @Override - protected UInt32Value convertAppObject(Integer appObject) { - return UInt32Value.of(appObject); - } - - @Override - public Class getAppObjectClass() { - return Integer.class; - } - - @Override - public Class getInputObjectClass() { - return UInt32Value.class; - } -} \ No newline at end of file diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/ULongTranslationSpec.java b/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/ULongTranslationSpec.java deleted file mode 100644 index 6308f9b..0000000 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/ULongTranslationSpec.java +++ /dev/null @@ -1,32 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; - -import com.google.protobuf.UInt64Value; - -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationSpec; - -/** - * TranslationSpec that defines how to convert from any Java Long to a Protobuf - * {@link UInt64Value} type and vice versa - */ -public class ULongTranslationSpec extends ProtobufTranslationSpec { - - @Override - protected Long convertInputObject(UInt64Value inputObject) { - return inputObject.getValue(); - } - - @Override - protected UInt64Value convertAppObject(Long appObject) { - return UInt64Value.of(appObject); - } - - @Override - public Class getAppObjectClass() { - return Long.class; - } - - @Override - public Class getInputObjectClass() { - return UInt64Value.class; - } -} diff --git a/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/core.proto b/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/core.proto index 3123fb3..eb9ac79 100644 --- a/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/core.proto +++ b/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/core.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package gov.hhs.aspr.ms.taskit.protobuf; option java_multiple_files = true; -option java_package = "gov.hhs.aspr.ms.taskit.protobuf.input"; +option java_package = "gov.hhs.aspr.ms.taskit.protobuf.objects"; message WrapperEnumValue { diff --git a/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject.proto b/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject.proto index 0addc8f..a9eac5e 100644 --- a/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject.proto +++ b/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject.proto @@ -2,17 +2,13 @@ syntax = "proto3"; package gov.hhs.aspr.ms.taskit.protobuf.testsupport; option java_multiple_files = true; -option java_package = "gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.input"; +option java_package = "gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects"; import "google/protobuf/any.proto"; -message TestComplexInputObjectSubObject { -} - message TestComplexInputObject { string testString = 1; double startTime = 2; int32 numEntities = 3; - TestComplexInputObjectSubObject subObject = 4; - google.protobuf.Any id = 5; + google.protobuf.Any id = 4; } \ No newline at end of file diff --git a/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject.proto b/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject.proto index ef69b4b..edcfd40 100644 --- a/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject.proto +++ b/protobuf/src/main/proto/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject.proto @@ -2,7 +2,7 @@ syntax = "proto3"; package gov.hhs.aspr.ms.taskit.protobuf.testsupport; option java_multiple_files = true; -option java_package = "gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input"; +option java_package = "gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects"; import "gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject.proto"; diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/core/ProtobufTranslationEngineTestHelper.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/core/ProtobufTranslationEngineTestHelper.java deleted file mode 100644 index 82c790c..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/core/ProtobufTranslationEngineTestHelper.java +++ /dev/null @@ -1,176 +0,0 @@ -package gov.hhs.aspr.ms.taskit.core; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectTranslator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestObjectWrapper; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.translationSpecs.TestProtobufComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs.TestProtobufObjectTranslationSpec; -import gov.hhs.aspr.ms.util.errors.ContractException; - -public final class ProtobufTranslationEngineTestHelper { - private ProtobufTranslationEngineTestHelper() { - } - - public static void testAddTranslationSpec(TranslationEngine.Builder builder) { - TestProtobufObjectTranslationSpec testObjectTranslationSpec = new TestProtobufObjectTranslationSpec(); - TestProtobufComplexObjectTranslationSpec testComplexObjectTranslationSpec = new TestProtobufComplexObjectTranslationSpec(); - TranslationEngine testTranslationEngine = builder.addTranslationSpec(testObjectTranslationSpec) - .addTranslationSpec(testComplexObjectTranslationSpec).build(); - - // show that the translation specs are retrievable by their own app and input - // classes - assertEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(testObjectTranslationSpec.getAppObjectClass())); - assertEquals(testObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(testObjectTranslationSpec.getInputObjectClass())); - - assertEquals(testComplexObjectTranslationSpec, - testTranslationEngine.getTranslationSpecForClass(testComplexObjectTranslationSpec.getAppObjectClass())); - assertEquals(testComplexObjectTranslationSpec, testTranslationEngine - .getTranslationSpecForClass(testComplexObjectTranslationSpec.getInputObjectClass())); - - builder.clearBuilder(); - // preconditions - // translationSpec is null - ContractException contractException = assertThrows(ContractException.class, () -> { - builder.addTranslationSpec(null); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_SPEC, contractException.getErrorType()); - - builder.clearBuilder(); - // the translation spec getAppClass method returns null - contractException = assertThrows(ContractException.class, () -> { - TranslationSpec wrapperTranslationSpec = new TranslationSpec() { - - @Override - protected Object convertInputObject(TestObjectWrapper inputObject) { - return inputObject.getWrappedObject(); - } - - @Override - protected TestObjectWrapper convertAppObject(Object appObject) { - TestObjectWrapper objectWrapper = new TestObjectWrapper(); - - objectWrapper.setWrappedObject(appObject); - - return objectWrapper; - } - - @Override - public Class getAppObjectClass() { - return null; - } - - @Override - public Class getInputObjectClass() { - return TestObjectWrapper.class; - } - }; - builder.addTranslationSpec(wrapperTranslationSpec); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_SPEC_APP_CLASS, contractException.getErrorType()); - - builder.clearBuilder(); - // the translation spec getInputClass method returns null - contractException = assertThrows(ContractException.class, () -> { - TranslationSpec wrapperTranslationSpec = new TranslationSpec() { - - @Override - protected Object convertInputObject(TestObjectWrapper inputObject) { - return inputObject.getWrappedObject(); - } - - @Override - protected TestObjectWrapper convertAppObject(Object appObject) { - TestObjectWrapper objectWrapper = new TestObjectWrapper(); - - objectWrapper.setWrappedObject(appObject); - - return objectWrapper; - } - - @Override - public Class getAppObjectClass() { - return Object.class; - } - - @Override - public Class getInputObjectClass() { - return null; - } - }; - builder.addTranslationSpec(wrapperTranslationSpec); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATION_SPEC_INPUT_CLASS, contractException.getErrorType()); - - builder.clearBuilder(); - // if the translation spec has already been added (same, but different - // instances) - contractException = assertThrows(ContractException.class, () -> { - TestProtobufObjectTranslationSpec testObjectTranslationSpec1 = new TestProtobufObjectTranslationSpec(); - TestProtobufObjectTranslationSpec testObjectTranslationSpec2 = new TestProtobufObjectTranslationSpec(); - - builder.addTranslationSpec(testObjectTranslationSpec1).addTranslationSpec(testObjectTranslationSpec2); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); - - builder.clearBuilder(); - // if the translation spec has already been added (exact same instance) - contractException = assertThrows(ContractException.class, () -> { - TestProtobufObjectTranslationSpec testObjectTranslationSpec1 = new TestProtobufObjectTranslationSpec(); - - builder.addTranslationSpec(testObjectTranslationSpec1).addTranslationSpec(testObjectTranslationSpec1); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATION_SPEC, contractException.getErrorType()); - } - - public static void testAddTranslator(TranslationEngine.Builder builder) { - builder.addTranslator(TestObjectTranslator.getTranslator()); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - builder.addTranslator(null); - }); - - assertEquals(CoreTranslationError.NULL_TRANSLATOR, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - builder.addTranslator(TestObjectTranslator.getTranslator()) - .addTranslator(TestObjectTranslator.getTranslator()); - }); - - assertEquals(CoreTranslationError.DUPLICATE_TRANSLATOR, contractException.getErrorType()); - } - - public static void testAddParentChildClassRelationship(TranslationEngine.Builder builder) { - builder.addParentChildClassRelationship(TestAppObject.class, Object.class); - - // preconditions - ContractException contractException = assertThrows(ContractException.class, () -> { - builder.addParentChildClassRelationship(null, Object.class); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - builder.addParentChildClassRelationship(TestAppObject.class, null); - }); - - assertEquals(CoreTranslationError.NULL_CLASS_REF, contractException.getErrorType()); - - contractException = assertThrows(ContractException.class, () -> { - builder.addParentChildClassRelationship(TestAppObject.class, Object.class) - .addParentChildClassRelationship(TestAppObject.class, Object.class); - }); - - assertEquals(CoreTranslationError.DUPLICATE_CLASSREF, contractException.getErrorType()); - } -} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufCoreTranslationError.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufCoreTranslationError.java deleted file mode 100644 index 992a665..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufCoreTranslationError.java +++ /dev/null @@ -1,31 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf; - -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.LinkedHashSet; -import java.util.Set; - -import org.junit.jupiter.api.Test; - -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; - -public class AT_ProtobufCoreTranslationError { - - @Test - @UnitTestMethod(target = ProtobufCoreTranslationError.class, name = "getDescription", args = {}) - public void testGetDescription() { - // show that each ErrorType has a non-null, non-empty description - for (ProtobufCoreTranslationError coreTranslationError : ProtobufCoreTranslationError.values()) { - assertNotNull(coreTranslationError.getDescription()); - assertTrue(coreTranslationError.getDescription().length() > 0); - } - - // show that each description is unique (ignoring case as well) - Set descriptions = new LinkedHashSet<>(); - for (ProtobufCoreTranslationError coreTranslationError : ProtobufCoreTranslationError.values()) { - boolean isUnique = descriptions.add(coreTranslationError.getDescription().toLowerCase()); - assertTrue(isUnique, coreTranslationError + " duplicates the description of another member"); - } - } -} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufTranslationEngine.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufTranslationEngine.java deleted file mode 100644 index fd3b957..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufTranslationEngine.java +++ /dev/null @@ -1,523 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.IOException; -import java.io.StringReader; -import java.nio.file.Path; -import java.util.Optional; - -import org.junit.jupiter.api.Test; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.protobuf.Any; -import com.google.protobuf.Descriptors.FieldDescriptor; -import com.google.protobuf.Int32Value; -import com.google.protobuf.InvalidProtocolBufferException; -import com.google.protobuf.Message; -import com.google.protobuf.ProtocolMessageEnum; - -import gov.hhs.aspr.ms.taskit.core.CoreTranslationError; -import gov.hhs.aspr.ms.taskit.core.ProtobufTranslationEngineTestHelper; -import gov.hhs.aspr.ms.taskit.core.TranslationSpec; -import gov.hhs.aspr.ms.taskit.core.Translator; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.translationSpecs.TestObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses.BadMessageBadArguments; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses.BadMessageIllegalAccess; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses.BadMessageNoMethod; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses.BadMessageNonStaticMethod; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.translationSpecs.TestProtobufComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputEnum; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs.TestProtobufObjectTranslationSpec; -import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; -import gov.hhs.aspr.ms.util.errors.ContractException; -import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; - -public class AT_ProtobufTranslationEngine { - Path basePath = ResourceHelper.getResourceDir(this.getClass()); - Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.class, name = "getAnyFromObject", args = { Object.class }) - public void testGetAnyFromObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - Integer integer = 1500; - Int32Value int32Value = Int32Value.of(integer); - Any expectedAny = Any.pack(int32Value); - - Any actualAny = protobufTranslationEngine.getAnyFromObject(integer); - - assertEquals(expectedAny, actualAny); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.class, name = "getAnyFromObjectAsSafeClass", args = { - Object.class, Class.class }) - public void testGetAnyFromObjectAsSafeClass() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - TestAppObject testAppObject = TestObjectUtil.generateTestAppObject(); - TestAppChildObject testAppChildObject = TestObjectUtil.getChildAppFromApp(testAppObject); - - TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(testAppChildObject); - Any expectedAny = Any.pack(expectedInputObject); - - Any actualAny = protobufTranslationEngine.getAnyFromObjectAsSafeClass(testAppChildObject, TestAppObject.class); - - assertEquals(expectedAny, actualAny); - - // preconditions - - // no translationSpec was provided for the parent class - ContractException contractException = assertThrows(ContractException.class, () -> { - ProtobufTranslationEngine protobufTranslationEngine2 = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - TestAppObject testAppObject2 = TestObjectUtil.generateTestAppObject(); - TestAppChildObject testAppChildObject2 = TestObjectUtil.getChildAppFromApp(testAppObject2); - - protobufTranslationEngine2.getAnyFromObjectAsSafeClass(testAppChildObject2, TestAppObject.class); - }); - - assertEquals(CoreTranslationError.UNKNOWN_TRANSLATION_SPEC, contractException.getErrorType()); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.class, name = "getObjectFromAny", args = { Any.class }) - public void testGetObjectFromAny() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - TestAppObject expectedObject = TestObjectUtil.generateTestAppObject(); - - TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedObject); - Any any = Any.pack(expectedInputObject); - - Object actualObject = protobufTranslationEngine.getObjectFromAny(any); - - assertTrue(actualObject.getClass() == TestAppObject.class); - assertEquals(expectedObject, actualObject); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.class, name = "getClassFromTypeUrl", args = { String.class }) - public void testGetClassFromTypeUrl() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - Class testInputObjectClass = TestInputObject.class; - Class testComplexInputObjectClass = TestComplexInputObject.class; - - String testInputObjectTypeUrl = TestInputObject.getDescriptor().getFullName(); - String testComplexInputObjectTypeUrl = TestComplexInputObject.getDescriptor().getFullName(); - - assertEquals(testInputObjectClass, protobufTranslationEngine.getClassFromTypeUrl(testInputObjectTypeUrl)); - assertEquals(testComplexInputObjectClass, - protobufTranslationEngine.getClassFromTypeUrl(testComplexInputObjectTypeUrl)); - - // preconditions - // no typeUrl was provided and/or malformed typeUrl - ContractException contractException = assertThrows(ContractException.class, () -> { - ProtobufTranslationEngine protobufTranslationEngine2 = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - protobufTranslationEngine2.getClassFromTypeUrl("badUrl"); - }); - - assertEquals(ProtobufCoreTranslationError.UNKNOWN_TYPE_URL, contractException.getErrorType()); - } - - @Test - @UnitTestForCoverage - public void testDebugPrint() throws IOException { - String fileName = "debugPrintFromEngine_1-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - protobufTranslationEngine.setDebug(true); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - protobufTranslationEngine.writeOutput(filePath.resolve(fileName), expectedAppObject, Optional.empty()); - TestAppObject actualAppObject = protobufTranslationEngine.readInput(filePath.resolve(fileName), - TestInputObject.class); - assertEquals(expectedAppObject, actualAppObject); - } - - @Test - @UnitTestForCoverage - public void testParseJson() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).setIgnoringUnknownFields(false) - .build(); - - // preconditions - // json has unknown property and the ignoringUnknownFields property is set to - // false - JsonObject jsonObject = new JsonObject(); - - jsonObject.addProperty("unknownProperty", "unknownValue"); - - RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { - protobufTranslationEngine.parseJson(new StringReader(jsonObject.toString()), TestInputObject.class); - }); - - assertEquals(InvalidProtocolBufferException.class, runtimeException.getCause().getClass()); - } - - @Test - @UnitTestForCoverage - public void testGetBuilderForMessage() { - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - // preconditions - /* - * Note on these preconditions: Because of the type enforced on readInput() - * ensuring that the passed in classRef is a child of Message.class, these - * preconditions should never be encountered. But for coverage purposes, are - * included here. - */ - // class ref does not contain a newBuilder method - assertThrows(RuntimeException.class, () -> { - protobufTranslationEngine.getBuilderForMessage(BadMessageNoMethod.class); - }); - - // class has a newBuilder method but it is not static - assertThrows(RuntimeException.class, () -> { - protobufTranslationEngine.getBuilderForMessage(BadMessageNonStaticMethod.class); - }); - - // class has a static newBuilder method but it takes arguments - assertThrows(RuntimeException.class, () -> { - protobufTranslationEngine.getBuilderForMessage(BadMessageBadArguments.class); - }); - - // class has a newBuilder method but it is not accessible - assertThrows(RuntimeException.class, () -> { - protobufTranslationEngine.getBuilderForMessage(BadMessageIllegalAccess.class); - }); - - } - - @Test - @UnitTestForCoverage - public void testReadInput() throws IOException { - String fileName = "readInputFromEngine_1-testOutput.json"; - String fileName2 = "readInputFromEngine_2-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - protobufTranslationEngine.writeOutput(filePath.resolve(fileName), expectedAppObject, Optional.empty()); - TestAppObject actualAppObject = protobufTranslationEngine.readInput(filePath.resolve(fileName), - TestInputObject.class); - assertEquals(expectedAppObject, actualAppObject); - - protobufTranslationEngine.writeOutput(filePath.resolve(fileName2), - TestObjectUtil.getChildAppFromApp(expectedAppObject), - Optional.of(TestAppObject.class)); - TestAppObject actualAppChildObject = protobufTranslationEngine.readInput(filePath.resolve(fileName2), - TestInputObject.class); - assertEquals(expectedAppObject, actualAppChildObject); - - // preconditions - // input class is not a Message class - ContractException contractException = assertThrows(ContractException.class, () -> { - protobufTranslationEngine.readInput(filePath.resolve(fileName2), TestAppObject.class); - }); - - assertEquals(ProtobufCoreTranslationError.INVALID_READ_INPUT_CLASS_REF, contractException.getErrorType()); - - // precondition for the Runtime exceptions are covered by the tests: - // testGetBuilderForMessage() and testParseJson() - } - - @Test - @UnitTestForCoverage - public void testWriteOutput() throws IOException { - String fileName = "writeOutputFromEngine_1-testOutput.json"; - String fileName2 = "writeOutputFromEngine_2-testOutput.json"; - - ResourceHelper.createFile(filePath, fileName); - ResourceHelper.createFile(filePath, fileName2); - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); - - protobufTranslationEngine.writeOutput(filePath.resolve(fileName), expectedAppObject, Optional.empty()); - TestAppObject actualAppObject = protobufTranslationEngine.readInput(filePath.resolve(fileName), - TestInputObject.class); - assertEquals(expectedAppObject, actualAppObject); - - protobufTranslationEngine.writeOutput(filePath.resolve(fileName2), - TestObjectUtil.getChildAppFromApp(expectedAppObject), - Optional.of(TestAppObject.class)); - TestAppObject actualAppChildObject = protobufTranslationEngine.readInput(filePath.resolve(fileName2), - TestInputObject.class); - assertEquals(expectedAppObject, actualAppChildObject); - - // this test is just for coverage, but this method should never be directly - // called - TestInputObject inputObject = TestObjectUtil.generateTestInputObject(); - protobufTranslationEngine.writeOutput(filePath.resolve(fileName2), inputObject, Optional.empty()); - actualAppObject = protobufTranslationEngine.readInput(filePath.resolve(fileName2), TestInputObject.class); - assertEquals(TestObjectUtil.getAppFromInput(inputObject), actualAppObject); - - // preconditions - // IO error occurs - RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { - protobufTranslationEngine.writeOutput(filePath.resolve("/foo"), expectedAppObject, Optional.empty()); - }); - - assertTrue(runtimeException.getCause() instanceof IOException); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.class, name = "builder", args = {}) - public void testBuilder() { - assertNotNull(ProtobufTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "build", args = {}) - public void testBuild() { - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - assertNotNull(protobufTranslationEngine); - - // parser and printer do not have equals contracts, so no way to check for - // equality - // the use cases for them are adequately tested in: testReadInput and - // testWriteOutput - } - - @Test - @UnitTestForCoverage - public void testGetDefaultMessage() { - ProtobufTranslationEngine.Builder pBuilder = ProtobufTranslationEngine.builder(); - - /* - * Note: because this method is only ever called if the classRef is an instance - * of Message.class, this method should never throw an exception. This test is - * here exclusively for test coverage. - */ - assertThrows(RuntimeException.class, () -> { - pBuilder.getDefaultMessage(Message.class); - }); - } - - @Test - @UnitTestForCoverage - public void testGetDefaultEnum() { - ProtobufTranslationEngine.Builder pBuilder = ProtobufTranslationEngine.builder(); - - /* - * Note: because this method is only ever called if the classRef is an instance - * of ProtocolMessageEnum.class, this method should never throw an exception. - * This test is here exclusively for test coverage. - */ - assertThrows(RuntimeException.class, () -> { - pBuilder.getDefaultEnum(ProtocolMessageEnum.class); - }); - } - - @Test - @UnitTestForCoverage - public void testPopulate() { - ProtobufTranslationEngine.Builder pBuilder = ProtobufTranslationEngine.builder(); - - // Protobuf Message - pBuilder.populate(TestInputObject.class); - - // Protobuf Enum - pBuilder.populate(TestInputEnum.class); - - // precondition - // if class is neither a Message nor a ProtocolMessageEnum - ContractException contractException = assertThrows(ContractException.class, () -> { - pBuilder.populate(TestAppObject.class); - }); - - assertEquals(ProtobufCoreTranslationError.INVALID_INPUT_CLASS, contractException.getErrorType()); - - // the class is exactly a Message.class - contractException = assertThrows(ContractException.class, () -> { - pBuilder.populate(Message.class); - }); - - assertEquals(ProtobufCoreTranslationError.INVALID_INPUT_CLASS, contractException.getErrorType()); - - // the class is exactly a ProtocolMessageEnum.class - contractException = assertThrows(ContractException.class, () -> { - pBuilder.populate(ProtocolMessageEnum.class); - }); - - assertEquals(ProtobufCoreTranslationError.INVALID_INPUT_CLASS, contractException.getErrorType()); - - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "addFieldToIncludeDefaultValue", args = { - FieldDescriptor.class }) - public void testAddFieldToIncludeDefaultValue() throws InvalidProtocolBufferException { - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addFieldToIncludeDefaultValue(TestInputObject.getDescriptor().findFieldByName("integer")).build(); - - TestInputObject expectedInputObject = TestObjectUtil.generateTestInputObject().toBuilder().setInteger(0) - .setBool(false).setString("").build(); - - String message = protobufTranslationEngine.getJsonPrinter().print(expectedInputObject); - - JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject(); - - assertTrue(jsonObject.has("integer")); - assertFalse(jsonObject.has("string")); - assertFalse(jsonObject.has("bool")); - - assertTrue(jsonObject.get("integer").isJsonPrimitive()); - assertEquals(0, jsonObject.get("integer").getAsInt()); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "addTranslationSpec", args = { - TranslationSpec.class }) - public void testAddTranslationSpec() { - ProtobufTranslationEngineTestHelper.testAddTranslationSpec(ProtobufTranslationEngine.builder()); - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufObjectTranslationSpec()) - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - - assertDoesNotThrow(() -> { - protobufTranslationEngine.getClassFromTypeUrl(TestInputObject.getDescriptor().getFullName()); - protobufTranslationEngine.getClassFromTypeUrl(TestComplexInputObject.getDescriptor().getFullName()); - }); - - // precondition - // translation spec is not a ProtobufTranslationSpec - - ContractException contractException = assertThrows(ContractException.class, () -> { - ProtobufTranslationEngine.builder().addTranslationSpec(new TestObjectTranslationSpec()); - }); - - assertEquals(ProtobufCoreTranslationError.INVALID_TRANSLATION_SPEC, contractException.getErrorType()); - // that the inputClass is not a Message nor a - // ProtocolMessageEnum, and is tested in the testPopulate() test - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "addTranslator", args = { - Translator.class }) - public void testAddTranslator() { - ProtobufTranslationEngineTestHelper.testAddTranslator(ProtobufTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "addParentChildClassRelationship", args = { - Class.class, Class.class }) - public void testAddParentChildClassRelationship() { - ProtobufTranslationEngineTestHelper.testAddParentChildClassRelationship(ProtobufTranslationEngine.builder()); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "setIgnoringUnknownFields", args = { - boolean.class }) - public void testSetIgnoringUnknownFields() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .setIgnoringUnknownFields(true).build(); - - JsonObject jsonObject = new JsonObject(); - - jsonObject.addProperty("bool", false); - jsonObject.addProperty("unknownField", "unknownField"); - - assertDoesNotThrow(() -> { - protobufTranslationEngine.getJsonParser().merge(jsonObject.toString(), TestInputObject.newBuilder()); - }); - - ProtobufTranslationEngine protobufTranslationEngine2 = ProtobufTranslationEngine.builder() - .setIgnoringUnknownFields(false).build(); - - assertThrows(InvalidProtocolBufferException.class, () -> { - protobufTranslationEngine2.getJsonParser().merge(jsonObject.toString(), TestInputObject.newBuilder()); - }); - - assertDoesNotThrow(() -> { - jsonObject.remove("unknownField"); - protobufTranslationEngine.getJsonParser().merge(jsonObject.toString(), TestInputObject.newBuilder()); - }); - } - - @Test - @UnitTestMethod(target = ProtobufTranslationEngine.Builder.class, name = "setIncludingDefaultValueFields", args = { - boolean.class }) - public void testSetIncludingDefaultValueFields() throws InvalidProtocolBufferException { - - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .setIncludingDefaultValueFields(true).build(); - - TestInputObject expectedInputObject = TestObjectUtil.generateTestInputObject().toBuilder().setInteger(0) - .setBool(false).setString("").build(); - - String message = protobufTranslationEngine.getJsonPrinter().print(expectedInputObject); - - JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject(); - - assertTrue(jsonObject.has("integer")); - assertTrue(jsonObject.has("string")); - assertTrue(jsonObject.has("bool")); - - assertTrue(jsonObject.get("integer").isJsonPrimitive()); - assertTrue(jsonObject.get("string").isJsonPrimitive()); - assertTrue(jsonObject.get("bool").isJsonPrimitive()); - - assertEquals(0, jsonObject.get("integer").getAsInt()); - assertEquals(false, jsonObject.get("bool").getAsBoolean()); - assertEquals("", jsonObject.get("string").getAsString()); - - protobufTranslationEngine = ProtobufTranslationEngine.builder().setIncludingDefaultValueFields(false).build(); - - message = protobufTranslationEngine.getJsonPrinter().print(expectedInputObject); - - jsonObject = JsonParser.parseString(message).getAsJsonObject(); - assertFalse(jsonObject.has("integer")); - assertFalse(jsonObject.has("string")); - assertFalse(jsonObject.has("bool")); - } -} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufTranslationSpec.java deleted file mode 100644 index 9755f15..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/AT_ProtobufTranslationSpec.java +++ /dev/null @@ -1,27 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; - -import com.google.protobuf.BoolValue; - -import gov.hhs.aspr.ms.taskit.core.TranslationEngine; -import gov.hhs.aspr.ms.taskit.protobuf.translationSpecs.BooleanTranslationSpec; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; - -public class AT_ProtobufTranslationSpec { - - @Test - @UnitTestMethod(target = ProtobufTranslationSpec.class, name = "init", args = { TranslationEngine.class }) - public void testInit() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - ProtobufTranslationSpec booleanTranslationSpec = new BooleanTranslationSpec(); - - booleanTranslationSpec.init(protobufTranslationEngine); - - assertTrue(booleanTranslationSpec.isInitialized()); - } - -} diff --git a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/usefulCode.txt b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/UsefulCode.java similarity index 84% rename from protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/usefulCode.txt rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/UsefulCode.java index 79e7b5d..2a46bbc 100644 --- a/protobuf/src/main/java/gov/hhs/aspr/ms/taskit/protobuf/usefulCode.txt +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/UsefulCode.java @@ -1,3 +1,11 @@ +package gov.hhs.aspr.ms.taskit.protobuf; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.protobuf.Descriptors.FileDescriptor; + +public class UsefulCode { public JsonObject deepMerge(JsonObject source, JsonObject target) { for (String key : source.keySet()) { JsonElement value = source.get(key); @@ -22,7 +30,7 @@ public JsonObject deepMerge(JsonObject source, JsonObject target) { } protected Class getClassFromInfo(FileDescriptor fileDescriptor, String typeName) { - boolean javaMultFiles = fileDescriptor.getOptions().getJavaMultipleFiles(); + boolean javaMultipleFiles = fileDescriptor.getOptions().getJavaMultipleFiles(); String javaPackage = fileDescriptor.getOptions().getJavaPackage(); String javaOuterClassName = fileDescriptor.getOptions().getJavaOuterClassname(); String protoName = fileDescriptor.getName().split("\\.")[0]; @@ -35,7 +43,7 @@ protected Class getClassFromInfo(FileDescriptor fileDescriptor, String typeNa sb.append(".") .append(javaOuterClassName) .append("$"); - } else if (!javaMultFiles) { + } else if (!javaMultipleFiles) { sb.append(".") .append(protoName.substring(0, 1).toUpperCase()) .append(protoName.substring(1)) @@ -54,3 +62,4 @@ protected Class getClassFromInfo(FileDescriptor fileDescriptor, String typeNa throw new RuntimeException(e); } } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufJsonTaskitEngine.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufJsonTaskitEngine.java new file mode 100644 index 0000000..65168e0 --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufJsonTaskitEngine.java @@ -0,0 +1,369 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.protobuf.Descriptors.FieldDescriptor; +import com.google.protobuf.InvalidProtocolBufferException; +import com.google.protobuf.Message; +import com.google.protobuf.ProtocolMessageEnum; + +import gov.hhs.aspr.ms.taskit.core.testsupport.engine.TestTaskitEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.complexobject.TestComplexObjectTranslatorId; +import gov.hhs.aspr.ms.taskit.core.testsupport.translation.object.specs.TestObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.ITranslationSpec; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.TestObjectUtil; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputEnum; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.ProtobufTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.AnyTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.BooleanTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.DateTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.DoubleTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.EnumTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.FloatTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.IntegerTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.LongTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.translation.specs.StringTranslationSpec; +import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +public class AT_ProtobufJsonTaskitEngine { + Path basePath = ResourceHelper.getResourceDir(this.getClass()); + Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); + + @Test + @UnitTestForCoverage + public void testReadFile() throws IOException { + String fileName = "readProtoJsonEngine_1-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject expectedObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + protobufTaskitEngine.translateAndWrite(filePath.resolve(fileName), expectedAppObject); + TestInputObject actualObject = protobufTaskitEngine.read(filePath.resolve(fileName), + TestInputObject.class); + assertEquals(expectedObject, actualObject); + + // preconditions + // json has unknown property and the ignoringUnknownFields property is set to + // false + ProtobufJsonTaskitEngine protobufTaskitEngine2 = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()) + .setIgnoringUnknownFields(false) + .build(); + + // use test engine to output bad json object + TestTaskitEngine testTaskitEngine = TestTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()).build(); + + JsonObject jsonObject = new JsonObject(); + + jsonObject.addProperty("unknownProperty", "unknownValue"); + + testTaskitEngine.write(filePath.resolve("readProtoJsonEngine_3_bad"), jsonObject); + + assertThrows(InvalidProtocolBufferException.class, () -> { + protobufTaskitEngine2.read(filePath.resolve("readProtoJsonEngine_3_bad"), TestInputObject.class); + }); + } + + @Test + @UnitTestForCoverage + public void testWriteFile() throws IOException { + String fileName = "writeProtoJsonEngine_1-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + TestAppObject expectedAppObject = TestObjectUtil.generateTestAppObject(); + TestInputObject testInputObject = TestObjectUtil.getInputFromApp(expectedAppObject); + + protobufTaskitEngine.write(filePath.resolve(fileName), testInputObject); + TestInputObject actualAppObject = protobufTaskitEngine.read(filePath.resolve(fileName), + TestInputObject.class); + assertEquals(testInputObject, actualAppObject); + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.class, name = "builder", args = {}) + public void testBuilder() { + // Nothing to test + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.Builder.class, name = "build", args = {}) + public void testBuild() { + + /* + * Test Note: build internally calls TaskitEngineData.build(). As such, the + * build method will also throw the exceptions from that method. Because that is + * already tested in Taskit, the precondition tests will not be tested here + */ + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + assertEquals(ProtobufTaskitEngineId.JSON_ENGINE_ID, protobufTaskitEngine.getTaskitEngineId()); + assertTrue(protobufTaskitEngine.isInitialized()); + + List> list = new ArrayList<>(); + + list.add(new BooleanTranslationSpec()); + list.add(new IntegerTranslationSpec()); + list.add(new LongTranslationSpec()); + list.add(new StringTranslationSpec()); + list.add(new FloatTranslationSpec()); + list.add(new DoubleTranslationSpec()); + list.add(new DateTranslationSpec()); + list.add(new EnumTranslationSpec()); + list.add(new AnyTranslationSpec()); + + for (ProtobufTranslationSpec translationSpec : list) { + translationSpec.init(protobufTaskitEngine); + } + + assertTrue(protobufTaskitEngine.getTranslationSpecs().containsAll(list)); + + // parser and printer do not have equals contracts, so no way to check for + // equality + // the use cases for them are adequately tested in: testReadInput and + // testWriteOutput + } + + @Test + @UnitTestForCoverage + public void testGetDefaultMessage() { + /* + * Note: because this method is only ever called if the classRef is an instance + * of Message.class, this method should never throw an exception. This test is + * here exclusively for test coverage. + */ + assertThrows(RuntimeException.class, () -> { + ProtobufTaskitEngineHelper.getDefaultMessage(Message.class); + }); + } + + @Test + @UnitTestForCoverage + public void testGetDefaultEnum() { + /* + * Note: because this method is only ever called if the classRef is an instance + * of ProtocolMessageEnum.class, this method should never throw an exception. + * This test is here exclusively for test coverage. + */ + assertThrows(RuntimeException.class, () -> { + ProtobufTaskitEngineHelper.getDefaultEnum(ProtocolMessageEnum.class); + }); + } + + @Test + @UnitTestForCoverage + public void testPopulate() { + ProtobufJsonTaskitEngine.Builder pBuilder = ProtobufJsonTaskitEngine.builder(); + + // Protobuf Message + pBuilder.populate(TestInputObject.class); + + // Protobuf Enum + pBuilder.populate(TestInputEnum.class); + + // precondition + // if class is neither a Message nor a ProtocolMessageEnum + ContractException contractException = assertThrows(ContractException.class, () -> { + pBuilder.populate(TestAppObject.class); + }); + + assertEquals(ProtobufTaskitError.INVALID_TRANSLATION_SPEC_INPUT_CLASS, contractException.getErrorType()); + + // the class is exactly a Message.class + contractException = assertThrows(ContractException.class, () -> { + pBuilder.populate(Message.class); + }); + + assertEquals(ProtobufTaskitError.INVALID_TRANSLATION_SPEC_INPUT_CLASS, contractException.getErrorType()); + + // the class is exactly a ProtocolMessageEnum.class + contractException = assertThrows(ContractException.class, () -> { + pBuilder.populate(ProtocolMessageEnum.class); + }); + + assertEquals(ProtobufTaskitError.INVALID_TRANSLATION_SPEC_INPUT_CLASS, contractException.getErrorType()); + + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.Builder.class, name = "addFieldToIncludeDefaultValue", args = { + FieldDescriptor.class }) + public void testAddFieldToIncludeDefaultValue() throws InvalidProtocolBufferException { + + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addFieldToIncludeDefaultValue(TestInputObject.getDescriptor().findFieldByName("integer")).build(); + + TestInputObject expectedInputObject = TestObjectUtil.generateTestInputObject().toBuilder().setInteger(0) + .setBool(false).setString("").build(); + + String message = protobufTaskitEngine.getJsonPrinter().print(expectedInputObject); + + JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject(); + + assertTrue(jsonObject.has("integer")); + assertFalse(jsonObject.has("string")); + assertFalse(jsonObject.has("bool")); + + assertTrue(jsonObject.get("integer").isJsonPrimitive()); + assertEquals(0, jsonObject.get("integer").getAsInt()); + + // preconditions + // field descriptor is null + ContractException contractException = assertThrows(ContractException.class, () -> { + ProtobufJsonTaskitEngine.builder() + .addFieldToIncludeDefaultValue(null); + }); + + assertEquals(ProtobufTaskitError.NULL_FIELD_DESCRIPTOR, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.Builder.class, name = "addTranslationSpec", args = { + ITranslationSpec.class }) + public void testAddTranslationSpec() { + // base functionality and preconditions tested by core. + // This test will only test the things specifically and uniquely done by the + // ProtobufJsonTaskitEngine + + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + assertDoesNotThrow(() -> { + protobufTaskitEngine.getClassFromTypeUrl(TestInputObject.getDescriptor().getFullName()); + protobufTaskitEngine.getClassFromTypeUrl(TestComplexInputObject.getDescriptor().getFullName()); + }); + + // precondition + // that the inputClass is not a Message nor a + // ProtocolMessageEnum, and is tested in the testPopulate() test + // translation spec is not a protobuf translation spec + ContractException contractException = assertThrows(ContractException.class, () -> { + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestObjectTranslationSpec()); + }); + + assertEquals(ProtobufTaskitError.INVALID_TRANSLATION_SPEC, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.Builder.class, name = "addTranslator", args = { + Translator.class }) + public void testAddTranslator() { + Translator translator = Translator.builder() + .setTranslatorId(TestComplexObjectTranslatorId.TRANSLATOR_ID) + .setInitializer(translatorContext -> { + translatorContext.getTaskitEngineBuilder(ProtobufJsonTaskitEngine.Builder.class) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()); + }) + .build(); + + ProtobufJsonTaskitEngine.builder() + .addTranslator(translator).build(); + + assertTrue(translator.isInitialized()); + + // preconditions tested by core + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.Builder.class, name = "setIgnoringUnknownFields", args = { + boolean.class }) + public void testSetIgnoringUnknownFields() { + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .setIgnoringUnknownFields(true).build(); + + JsonObject jsonObject = new JsonObject(); + + jsonObject.addProperty("bool", false); + jsonObject.addProperty("unknownField", "unknownField"); + + assertDoesNotThrow(() -> { + protobufTaskitEngine.getJsonParser().merge(jsonObject.toString(), TestInputObject.newBuilder()); + }); + + ProtobufJsonTaskitEngine protobufTaskitEngine2 = ProtobufJsonTaskitEngine.builder() + .setIgnoringUnknownFields(false).build(); + + assertThrows(InvalidProtocolBufferException.class, () -> { + protobufTaskitEngine2.getJsonParser().merge(jsonObject.toString(), TestInputObject.newBuilder()); + }); + + assertDoesNotThrow(() -> { + jsonObject.remove("unknownField"); + protobufTaskitEngine.getJsonParser().merge(jsonObject.toString(), TestInputObject.newBuilder()); + }); + } + + @Test + @UnitTestMethod(target = ProtobufJsonTaskitEngine.Builder.class, name = "setIncludingDefaultValueFields", args = { + boolean.class }) + public void testSetIncludingDefaultValueFields() throws InvalidProtocolBufferException { + + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .setIncludingDefaultValueFields(true).build(); + + TestInputObject expectedInputObject = TestObjectUtil.generateTestInputObject().toBuilder().setInteger(0) + .setBool(false).setString("").build(); + + String message = protobufTaskitEngine.getJsonPrinter().print(expectedInputObject); + + JsonObject jsonObject = JsonParser.parseString(message).getAsJsonObject(); + + assertTrue(jsonObject.has("integer")); + assertTrue(jsonObject.has("string")); + assertTrue(jsonObject.has("bool")); + + assertTrue(jsonObject.get("integer").isJsonPrimitive()); + assertTrue(jsonObject.get("string").isJsonPrimitive()); + assertTrue(jsonObject.get("bool").isJsonPrimitive()); + + assertEquals(0, jsonObject.get("integer").getAsInt()); + assertEquals(false, jsonObject.get("bool").getAsBoolean()); + assertEquals("", jsonObject.get("string").getAsString()); + + protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().setIncludingDefaultValueFields(false).build(); + + message = protobufTaskitEngine.getJsonPrinter().print(expectedInputObject); + + jsonObject = JsonParser.parseString(message).getAsJsonObject(); + assertFalse(jsonObject.has("integer")); + assertFalse(jsonObject.has("string")); + assertFalse(jsonObject.has("bool")); + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngine.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngine.java new file mode 100644 index 0000000..7ce1dbe --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngine.java @@ -0,0 +1,281 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.nio.file.Path; + +import org.junit.jupiter.api.Test; + +import com.google.protobuf.Any; +import com.google.protobuf.Int32Value; + +import gov.hhs.aspr.ms.taskit.core.engine.TaskitError; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.TestObjectUtil; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.BadMessageBadArguments; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.BadMessageIllegalAccess; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.BadMessageNoMethod; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.BadMessageNonStaticMethod; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufObjectTranslationSpec; +import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; +import gov.hhs.aspr.ms.util.errors.ContractException; +import gov.hhs.aspr.ms.util.resourcehelper.ResourceHelper; + +public class AT_ProtobufTaskitEngine { + Path basePath = ResourceHelper.getResourceDir(this.getClass()); + Path filePath = ResourceHelper.createDirectory(basePath, "test-output"); + + @Test + @UnitTestForCoverage + public void testReadFile() { + String fileName = "readProtoEngine_1-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + // preconditions + // input class is not a Message class + ContractException contractException = assertThrows(ContractException.class, () -> { + protobufTaskitEngine.read(filePath.resolve(fileName), TestAppObject.class); + }); + + assertEquals(TaskitError.INVALID_INPUT_CLASS, contractException.getErrorType()); + + /* + * Note on these preconditions: Because of the type enforced on readInput() + * ensuring that the passed in classRef is a child of Message.class, these + * preconditions should never be encountered. But for coverage purposes, are + * included here. + */ + // class ref does not contain a newBuilder method + assertThrows(RuntimeException.class, () -> { + ProtobufTaskitEngineHelper.getBuilderForMessage(BadMessageNoMethod.class); + }); + + // class has a newBuilder method but it is not static + assertThrows(RuntimeException.class, () -> { + ProtobufTaskitEngineHelper.getBuilderForMessage(BadMessageNonStaticMethod.class); + }); + + // class has a static newBuilder method but it takes arguments + assertThrows(RuntimeException.class, () -> { + ProtobufTaskitEngineHelper.getBuilderForMessage(BadMessageBadArguments.class); + }); + + // class has a newBuilder method but it is not accessible + assertThrows(RuntimeException.class, () -> { + ProtobufTaskitEngineHelper.getBuilderForMessage(BadMessageIllegalAccess.class); + }); + } + + @Test + @UnitTestForCoverage + public void testWriteFile() { + String fileName = "writeProtoEngine_1-testOutput.json"; + + ResourceHelper.createFile(filePath, fileName); + + ProtobufTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + // preconditions + // the object to write isn't assignable from Message.class + ContractException contractException = assertThrows(ContractException.class, () -> { + protobufTaskitEngine.write(filePath.resolve(fileName), TestObjectUtil.generateTestAppObject()); + }); + + assertEquals(TaskitError.INVALID_OUTPUT_CLASS, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = ProtobufTaskitEngine.class, name = "getAnyFromObject", args = { Object.class }) + public void testGetAnyFromObject() { + /* + * Test Note: because this method internally calls translateObject(), it + * necessarily throws the same exceptions as that method. Because those + * exceptions are tested in Taskit, we won't additionally test them here. + */ + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); + + Integer integer = 1500; + Int32Value int32Value = Int32Value.of(integer); + Any expectedAny = Any.pack(int32Value); + + Any actualAny = protobufTaskitEngine.getAnyFromObject(integer); + + assertEquals(expectedAny, actualAny); + } + + @Test + @UnitTestMethod(target = ProtobufTaskitEngine.class, name = "getAnyFromObjectAsClassSafe", args = { + Object.class, Class.class }) + public void testGetAnyFromObjectAsClassSafe() { + /* + * Test Note: because this method internally calls translateObjectAsClassSafe() + * and translateObjectAsClassUnsafe, it + * necessarily throws the same exceptions as those methods. Because those + * exceptions are tested in Taskit, we won't additionally test them here. + */ + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + TestAppObject testAppObject = TestObjectUtil.generateTestAppObject(); + TestAppChildObject testAppChildObject = TestObjectUtil.getChildAppFromApp(testAppObject); + + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(testAppChildObject); + Any expectedAny = Any.pack(expectedInputObject); + + Any actualAny = protobufTaskitEngine.getAnyFromObjectAsClassSafe(testAppChildObject, + TestAppObject.class); + + assertEquals(expectedAny, actualAny); + } + + @Test + @UnitTestMethod(target = ProtobufTaskitEngine.class, name = "getObjectFromAny", args = { Any.class }) + public void testGetObjectFromAny() { + /* + * Test Note: because this method internally calls + * translateObjectAsClassUnsafe(), it + * necessarily throws the same exceptions as that method. Because those + * exceptions are tested in Taskit, we won't additionally test them here. + */ + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + TestAppObject expectedObject = TestObjectUtil.generateTestAppObject(); + + TestInputObject expectedInputObject = TestObjectUtil.getInputFromApp(expectedObject); + Any any = Any.pack(expectedInputObject); + + Object actualObject = protobufTaskitEngine.getObjectFromAny(any); + + assertTrue(actualObject.getClass() == TestAppObject.class); + assertEquals(expectedObject, actualObject); + } + + @Test + @UnitTestMethod(target = ProtobufTaskitEngine.class, name = "getClassFromTypeUrl", args = { String.class }) + public void testGetClassFromTypeUrl() { + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + Class testInputObjectClass = TestInputObject.class; + Class testComplexInputObjectClass = TestComplexInputObject.class; + + String testInputObjectTypeUrl = TestInputObject.getDescriptor().getFullName(); + String testComplexInputObjectTypeUrl = TestComplexInputObject.getDescriptor().getFullName(); + + assertEquals(testInputObjectClass, protobufTaskitEngine.getClassFromTypeUrl(testInputObjectTypeUrl)); + assertEquals(testComplexInputObjectClass, + protobufTaskitEngine.getClassFromTypeUrl(testComplexInputObjectTypeUrl)); + + // preconditions + // no typeUrl was provided and/or malformed typeUrl + ContractException contractException = assertThrows(ContractException.class, () -> { + ProtobufJsonTaskitEngine protobufTaskitEngine2 = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); + + protobufTaskitEngine2.getClassFromTypeUrl("badUrl"); + }); + + assertEquals(ProtobufTaskitError.UNKNOWN_TYPE_URL, contractException.getErrorType()); + } + + @Test + @UnitTestMethod(target = ProtobufTaskitEngine.class, name = "hashCode", args = {}) + public void testHashCode() { + // TODO: update test + ProtobufTaskitEngine protobufTaskitEngine1 = ProtobufJsonTaskitEngine.builder() + .build(); + ProtobufTaskitEngine protobufTaskitEngine2 = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .build(); + ProtobufTaskitEngine protobufTaskitEngine3 = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()) + .build(); + ProtobufTaskitEngine protobufTaskitEngine4 = ProtobufJsonTaskitEngine.builder() + .build(); + + // exact same + assertEquals(protobufTaskitEngine1.hashCode(), protobufTaskitEngine1.hashCode()); + assertEquals(protobufTaskitEngine2.hashCode(), protobufTaskitEngine2.hashCode()); + assertEquals(protobufTaskitEngine3.hashCode(), protobufTaskitEngine3.hashCode()); + assertEquals(protobufTaskitEngine4.hashCode(), protobufTaskitEngine4.hashCode()); + + // super not equals + assertNotEquals(protobufTaskitEngine1.hashCode(), protobufTaskitEngine2.hashCode()); + assertNotEquals(protobufTaskitEngine1.hashCode(), protobufTaskitEngine3.hashCode()); + assertNotEquals(protobufTaskitEngine2.hashCode(), protobufTaskitEngine1.hashCode()); + assertNotEquals(protobufTaskitEngine2.hashCode(), protobufTaskitEngine3.hashCode()); + assertNotEquals(protobufTaskitEngine2.hashCode(), protobufTaskitEngine4.hashCode()); + assertNotEquals(protobufTaskitEngine3.hashCode(), protobufTaskitEngine1.hashCode()); + assertNotEquals(protobufTaskitEngine3.hashCode(), protobufTaskitEngine2.hashCode()); + assertNotEquals(protobufTaskitEngine3.hashCode(), protobufTaskitEngine4.hashCode()); + assertNotEquals(protobufTaskitEngine4.hashCode(), protobufTaskitEngine2.hashCode()); + assertNotEquals(protobufTaskitEngine4.hashCode(), protobufTaskitEngine3.hashCode()); + + // same specs + assertEquals(protobufTaskitEngine1.hashCode(), protobufTaskitEngine4.hashCode()); + assertEquals(protobufTaskitEngine4.hashCode(), protobufTaskitEngine1.hashCode()); + } + + @Test + @UnitTestMethod(target = ProtobufTaskitEngine.class, name = "equals", args = { Object.class }) + public void testEquals() { + // TODO: update test + ProtobufTaskitEngine protobufTaskitEngine1 = ProtobufJsonTaskitEngine.builder() + .build(); + ProtobufTaskitEngine protobufTaskitEngine2 = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufObjectTranslationSpec()) + .build(); + ProtobufTaskitEngine protobufTaskitEngine3 = ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()) + .build(); + ProtobufTaskitEngine protobufTaskitEngine4 = ProtobufJsonTaskitEngine.builder() + .build(); + + // exact same + assertEquals(protobufTaskitEngine1, protobufTaskitEngine1); + assertEquals(protobufTaskitEngine2, protobufTaskitEngine2); + assertEquals(protobufTaskitEngine3, protobufTaskitEngine3); + assertEquals(protobufTaskitEngine4, protobufTaskitEngine4); + + // null + assertNotEquals(protobufTaskitEngine1, null); + + // not instance + assertNotEquals(protobufTaskitEngine1, new Object()); + + // super not equals + assertNotEquals(protobufTaskitEngine1, protobufTaskitEngine2); + assertNotEquals(protobufTaskitEngine1, protobufTaskitEngine3); + assertNotEquals(protobufTaskitEngine2, protobufTaskitEngine1); + assertNotEquals(protobufTaskitEngine2, protobufTaskitEngine3); + assertNotEquals(protobufTaskitEngine2, protobufTaskitEngine4); + assertNotEquals(protobufTaskitEngine3, protobufTaskitEngine1); + assertNotEquals(protobufTaskitEngine3, protobufTaskitEngine2); + assertNotEquals(protobufTaskitEngine3, protobufTaskitEngine4); + assertNotEquals(protobufTaskitEngine4, protobufTaskitEngine2); + assertNotEquals(protobufTaskitEngine4, protobufTaskitEngine3); + + // same specs + assertEquals(protobufTaskitEngine1, protobufTaskitEngine4); + assertEquals(protobufTaskitEngine4, protobufTaskitEngine1); + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngineHelper.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngineHelper.java new file mode 100644 index 0000000..a97ea8f --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngineHelper.java @@ -0,0 +1,14 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; + +public class AT_ProtobufTaskitEngineHelper { + @Test + @UnitTestForCoverage + public void testGetBuilderForMessage() { + + + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngineId.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngineId.java new file mode 100644 index 0000000..9a8aba5 --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitEngineId.java @@ -0,0 +1,22 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.util.annotations.UnitTestField; + +public class AT_ProtobufTaskitEngineId { + + @Test + @UnitTestField(target = ProtobufTaskitEngineId.class, name = "JSON_ENGINE_ID") + public void testJsonTaskitEngineId() { + assertNotNull(ProtobufTaskitEngineId.JSON_ENGINE_ID); + } + + @Test + @UnitTestField(target = ProtobufTaskitEngineId.class, name = "BINARY_ENGINE_ID") + public void testBinaryTaskitEngineId() { + assertNotNull(ProtobufTaskitEngineId.BINARY_ENGINE_ID); + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitError.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitError.java new file mode 100644 index 0000000..51f3ce2 --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/engine/AT_ProtobufTaskitError.java @@ -0,0 +1,31 @@ +package gov.hhs.aspr.ms.taskit.protobuf.engine; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; + +public class AT_ProtobufTaskitError { + + @Test + @UnitTestMethod(target = ProtobufTaskitError.class, name = "getDescription", args = {}) + public void testGetDescription() { + // show that each ErrorType has a non-null, non-empty description + for (ProtobufTaskitError protobufTaskitError : ProtobufTaskitError.values()) { + assertNotNull(protobufTaskitError.getDescription()); + assertTrue(protobufTaskitError.getDescription().length() > 0); + } + + // show that each description is unique (ignoring case as well) + Set descriptions = new LinkedHashSet<>(); + for (ProtobufTaskitError protobufTaskitError : ProtobufTaskitError.values()) { + boolean isUnique = descriptions.add(protobufTaskitError.getDescription().toLowerCase()); + assertTrue(isUnique, protobufTaskitError + " duplicates the description of another member"); + } + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/TestObjectUtil.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/TestObjectUtil.java index ca84f69..9d49080 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/TestObjectUtil.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/TestObjectUtil.java @@ -3,13 +3,13 @@ import java.util.ArrayList; import java.util.List; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppChildObject; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppEnum; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.input.TestComplexInputObject; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputEnum; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppChildObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppEnum; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputEnum; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputObject; import gov.hhs.aspr.ms.util.random.RandomGeneratorProvider; public class TestObjectUtil { diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageBadArguments.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageBadArguments.java similarity index 77% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageBadArguments.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageBadArguments.java index 6e71835..2ed3970 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageBadArguments.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageBadArguments.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects; public class BadMessageBadArguments { diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageIllegalAccess.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageIllegalAccess.java similarity index 76% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageIllegalAccess.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageIllegalAccess.java index d574078..9aef6e9 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageIllegalAccess.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageIllegalAccess.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects; public class BadMessageIllegalAccess { private BadMessageIllegalAccess() { diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageNoMethod.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageNoMethod.java new file mode 100644 index 0000000..3b690af --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageNoMethod.java @@ -0,0 +1,5 @@ +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects; + +public class BadMessageNoMethod { + +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageNonStaticMethod.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageNonStaticMethod.java similarity index 77% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageNonStaticMethod.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageNonStaticMethod.java index f906e14..4b6705c 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageNonStaticMethod.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/objects/BadMessageNonStaticMethod.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects; /* * Class that has newBuilder method but it is not static diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageNoMethod.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageNoMethod.java deleted file mode 100644 index 488db65..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testClasses/BadMessageNoMethod.java +++ /dev/null @@ -1,5 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testClasses; - -public class BadMessageNoMethod { - -} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject/translationSpecs/AT_TestProtobufComplexObjectTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufComplexObjectTranslationSpec.java similarity index 72% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject/translationSpecs/AT_TestProtobufComplexObjectTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufComplexObjectTranslationSpec.java index fbf5f26..a4690fe 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testcomplexobject/translationSpecs/AT_TestProtobufComplexObjectTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufComplexObjectTranslationSpec.java @@ -1,14 +1,14 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.Test; -import gov.hhs.aspr.ms.taskit.core.testsupport.testcomplexobject.TestComplexAppObject; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestComplexAppObject; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.taskit.protobuf.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.input.TestComplexInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestComplexInputObject; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -24,16 +24,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - TestProtobufComplexObjectTranslationSpec complexObjectTranslationSpec = new TestProtobufComplexObjectTranslationSpec(); - complexObjectTranslationSpec.init(protobufTranslationEngine); + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(complexObjectTranslationSpec) + .build(); TestComplexAppObject expectedValue = TestObjectUtil.generateTestComplexAppObject(); TestComplexInputObject inputValue = TestObjectUtil.getComplexInputFromComplexApp(expectedValue); - TestComplexAppObject actualValue = complexObjectTranslationSpec.convertInputObject(inputValue); + TestComplexAppObject actualValue = complexObjectTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -41,16 +40,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - TestProtobufComplexObjectTranslationSpec complexObjectTranslationSpec = new TestProtobufComplexObjectTranslationSpec(); - complexObjectTranslationSpec.init(protobufTranslationEngine); + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(complexObjectTranslationSpec) + .build(); TestComplexAppObject appValue = TestObjectUtil.generateTestComplexAppObject(); TestComplexInputObject expectedValue = TestObjectUtil.getComplexInputFromComplexApp(appValue); - TestComplexInputObject actualValue = complexObjectTranslationSpec.convertAppObject(appValue); + TestComplexInputObject actualValue = complexObjectTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/AT_TestProtobufEnumTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufEnumTranslationSpec.java similarity index 71% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/AT_TestProtobufEnumTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufEnumTranslationSpec.java index 54d5e11..d1912cd 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/AT_TestProtobufEnumTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufEnumTranslationSpec.java @@ -1,13 +1,13 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.Test; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppEnum; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputEnum; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppEnum; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputEnum; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,16 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - TestProtobufEnumTranslationSpec enumTranslationSpec = new TestProtobufEnumTranslationSpec(); - enumTranslationSpec.init(protobufTranslationEngine); + + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(enumTranslationSpec) + .build(); TestAppEnum expectedValue = TestAppEnum.TEST1; TestInputEnum inputValue = TestInputEnum.TEST1; - TestAppEnum actualValue = enumTranslationSpec.convertInputObject(inputValue); + TestAppEnum actualValue = enumTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +40,16 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - TestProtobufEnumTranslationSpec enumTranslationSpec = new TestProtobufEnumTranslationSpec(); - enumTranslationSpec.init(protobufTranslationEngine); + + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(enumTranslationSpec) + .build(); TestAppEnum appValue = TestAppEnum.TEST2; TestInputEnum expectedValue = TestInputEnum.TEST2; - TestInputEnum actualValue = enumTranslationSpec.convertAppObject(appValue); + TestInputEnum actualValue = enumTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/AT_TestProtobufObjectTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufObjectTranslationSpec.java similarity index 70% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/AT_TestProtobufObjectTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufObjectTranslationSpec.java index 795a178..d9d1033 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/testobject/translationSpecs/AT_TestProtobufObjectTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/testsupport/translation/specs/AT_TestProtobufObjectTranslationSpec.java @@ -1,15 +1,14 @@ -package gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import org.junit.jupiter.api.Test; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppObject; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppObject; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.taskit.protobuf.testsupport.TestObjectUtil; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.translationSpecs.TestProtobufComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputObject; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -25,16 +24,17 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - TestProtobufObjectTranslationSpec objectTranslationSpec = new TestProtobufObjectTranslationSpec(); - objectTranslationSpec.init(protobufTranslationEngine); + + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(objectTranslationSpec) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()) + .build(); TestAppObject expectedValue = TestObjectUtil.generateTestAppObject(); TestInputObject inputValue = TestObjectUtil.getInputFromApp(expectedValue); - TestAppObject actualValue = objectTranslationSpec.convertInputObject(inputValue); + TestAppObject actualValue = objectTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -42,16 +42,17 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() - .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); - TestProtobufObjectTranslationSpec objectTranslationSpec = new TestProtobufObjectTranslationSpec(); - objectTranslationSpec.init(protobufTranslationEngine); + + ProtobufJsonTaskitEngine.builder() + .addTranslationSpec(objectTranslationSpec) + .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()) + .build(); TestAppObject appValue = TestObjectUtil.generateTestAppObject(); TestInputObject expectedValue = TestObjectUtil.getInputFromApp(appValue); - TestInputObject actualValue = objectTranslationSpec.convertAppObject(appValue); + TestInputObject actualValue = objectTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/AT_ProtobufTranslator.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/AT_ProtobufTranslator.java new file mode 100644 index 0000000..9d170e8 --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/AT_ProtobufTranslator.java @@ -0,0 +1,37 @@ +package gov.hhs.aspr.ms.taskit.protobuf.translation; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Set; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.taskit.core.testsupport.TranslatorTestSupport; +import gov.hhs.aspr.ms.taskit.core.translation.Translator; +import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; +import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; + +public class AT_ProtobufTranslator { + + @Test + @UnitTestForCoverage + public void testGetTranslationSpecs() throws ClassNotFoundException { + Set missing = TranslatorTestSupport.testGetTranslationSpecs(ProtobufTranslator.class, + ProtobufTranslator.getTranslationSpecs()); + + assertTrue(missing.isEmpty(), missing.toString()); + } + + @Test + @UnitTestMethod(target = ProtobufTranslator.class, name = "getTranslator", args = {}) + public void testGetTranslator() { + Translator expectedTranslator = Translator.builder() + .setTranslatorId(ProtobufTranslatorId.TRANSLATOR_ID) + .setInitializer((translatorContext) -> { + }) + .build(); + + assertEquals(expectedTranslator, ProtobufTranslator.getTranslator()); + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/AT_ProtobufTranslatorId.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/AT_ProtobufTranslatorId.java new file mode 100644 index 0000000..558e9c5 --- /dev/null +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/AT_ProtobufTranslatorId.java @@ -0,0 +1,15 @@ +package gov.hhs.aspr.ms.taskit.protobuf.translation; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +import org.junit.jupiter.api.Test; + +import gov.hhs.aspr.ms.util.annotations.UnitTestField; + +public class AT_ProtobufTranslatorId { + @Test + @UnitTestField(target = ProtobufTranslatorId.class, name = "TRANSLATOR_ID") + public void testTranslatorId() { + assertNotNull(ProtobufTranslatorId.TRANSLATOR_ID); + } +} diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_AnyTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_AnyTranslationSpec.java similarity index 71% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_AnyTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_AnyTranslationSpec.java index 9caf26b..5e39747 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_AnyTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_AnyTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -10,20 +10,20 @@ import com.google.protobuf.Int32Value; import com.google.protobuf.InvalidProtocolBufferException; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppEnum; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; -import gov.hhs.aspr.ms.taskit.protobuf.input.WrapperEnumValue; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testcomplexobject.translationSpecs.TestProtobufComplexObjectTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputEnum; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputObject; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs.TestProtobufEnumTranslationSpec; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs.TestProtobufObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppEnum; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; +import gov.hhs.aspr.ms.taskit.protobuf.objects.WrapperEnumValue; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputEnum; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputObject; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufComplexObjectTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufEnumTranslationSpec; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufObjectTranslationSpec; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; /** - * TranslationSpec that defines how to convert from any Java Object to a + * TranslationSpec that defines how to translate from any Java Object to a * Protobuf {@link Any} type and vice versa */ public class AT_AnyTranslationSpec { @@ -37,20 +37,21 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() .addTranslationSpec(new TestProtobufEnumTranslationSpec()) .addTranslationSpec(new TestProtobufObjectTranslationSpec()) .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); AnyTranslationSpec anyTranslationSpec = new AnyTranslationSpec(); - anyTranslationSpec.init(protobufTranslationEngine); + + anyTranslationSpec.init(protobufTaskitEngine); Integer expectedValue = 100; Int32Value int32Value = Int32Value.of(expectedValue); Any any = Any.pack(int32Value); - Object obj = anyTranslationSpec.convertInputObject(any); + Object obj = anyTranslationSpec.translateInputObject(any); assertEquals(expectedValue, obj); @@ -58,7 +59,7 @@ public void testConvertInputObject() { // the type url of the any is malformed RuntimeException runtimeException = assertThrows(RuntimeException.class, () -> { Any badAny = Any.newBuilder().setTypeUrl("badTypeUrl").build(); - anyTranslationSpec.convertInputObject(badAny); + anyTranslationSpec.translateInputObject(badAny); }); assertEquals("Malformed type url", runtimeException.getMessage()); @@ -67,7 +68,7 @@ public void testConvertInputObject() { runtimeException = assertThrows(RuntimeException.class, () -> { Any badAny = Any.newBuilder().setTypeUrl("/" + TestInputEnum.TEST1.getDescriptorForType().getFullName()) .build(); - anyTranslationSpec.convertInputObject(badAny); + anyTranslationSpec.translateInputObject(badAny); }); assertEquals("Message is not assignable from " + TestInputEnum.class.getName(), runtimeException.getMessage()); @@ -79,13 +80,14 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testUnpackMessage() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() .addTranslationSpec(new TestProtobufEnumTranslationSpec()) .addTranslationSpec(new TestProtobufObjectTranslationSpec()) .addTranslationSpec(new TestProtobufComplexObjectTranslationSpec()).build(); AnyTranslationSpec anyTranslationSpec = new AnyTranslationSpec(); - anyTranslationSpec.init(protobufTranslationEngine); + + anyTranslationSpec.init(protobufTaskitEngine); Integer expectedValue = 100; Int32Value int32Value = Int32Value.of(expectedValue); @@ -103,23 +105,24 @@ public void testUnpackMessage() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() .addTranslationSpec(new TestProtobufEnumTranslationSpec()).build(); AnyTranslationSpec anyTranslationSpec = new AnyTranslationSpec(); - anyTranslationSpec.init(protobufTranslationEngine); - // app object converted into any + anyTranslationSpec.init(protobufTaskitEngine); + + // app object translateed into any Integer value = 100; Int32Value expectedValue = Int32Value.of(value); Any expectedAny = Any.pack(expectedValue); - Any actualAny = anyTranslationSpec.convertAppObject(value); + Any actualAny = anyTranslationSpec.translateAppObject(value); assertEquals(expectedAny, actualAny); - // app enum converted into any by wrapping it in a WrapperEnumValue + // app enum translateed into any by wrapping it in a WrapperEnumValue TestAppEnum appValue = TestAppEnum.TEST1; TestInputEnum expectedValueEnum = TestInputEnum.TEST1; @@ -128,14 +131,14 @@ public void testConvertAppObject() { expectedAny = Any.pack(wrapperEnumValue); - actualAny = anyTranslationSpec.convertAppObject(appValue); + actualAny = anyTranslationSpec.translateAppObject(appValue); assertEquals(expectedAny, actualAny); - // by calling covert on an object that was already converted + // by calling covert on an object that was already translateed // this case is specifically used for - // ProtobufTranslationEngine.testGetAnyFromObjectAsSafeClass - actualAny = anyTranslationSpec.convertAppObject(wrapperEnumValue); + // ProtobufTaskitEngine.testGetAnyFromObjectAsSafeClass + actualAny = anyTranslationSpec.translateAppObject(wrapperEnumValue); assertEquals(expectedAny, actualAny); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_BooleanTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_BooleanTranslationSpec.java similarity index 74% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_BooleanTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_BooleanTranslationSpec.java index 0cb1de6..84abecb 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_BooleanTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_BooleanTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -7,7 +7,7 @@ import com.google.protobuf.BoolValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - BooleanTranslationSpec booleanTranslationSpec = new BooleanTranslationSpec(); - booleanTranslationSpec.init(protobufTranslationEngine); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); + + booleanTranslationSpec.init(protobufTaskitEngine); Boolean expectedValue = false; BoolValue inputValue = BoolValue.of(false); - Boolean actualValue = booleanTranslationSpec.convertInputObject(inputValue); + Boolean actualValue = booleanTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +39,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); BooleanTranslationSpec booleanTranslationSpec = new BooleanTranslationSpec(); - booleanTranslationSpec.init(protobufTranslationEngine); + booleanTranslationSpec.init(protobufTaskitEngine); Boolean appValue = false; BoolValue expectedValue = BoolValue.of(false); - BoolValue actualValue = booleanTranslationSpec.convertAppObject(appValue); + BoolValue actualValue = booleanTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_DateTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_DateTranslationSpec.java similarity index 77% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_DateTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_DateTranslationSpec.java index 9b8dba9..eee630f 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_DateTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_DateTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -9,7 +9,7 @@ import com.google.type.Date; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -25,16 +25,16 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); DateTranslationSpec dateTranslationSpec = new DateTranslationSpec(); - dateTranslationSpec.init(protobufTranslationEngine); + dateTranslationSpec.init(protobufTaskitEngine); LocalDate expectedValue = LocalDate.now(); Date inputValue = Date.newBuilder().setDay(expectedValue.getDayOfMonth()) .setMonth(expectedValue.getMonthValue()).setYear(expectedValue.getYear()).build(); - LocalDate actualValue = dateTranslationSpec.convertInputObject(inputValue); + LocalDate actualValue = dateTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -42,16 +42,16 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); DateTranslationSpec dateTranslationSpec = new DateTranslationSpec(); - dateTranslationSpec.init(protobufTranslationEngine); + dateTranslationSpec.init(protobufTaskitEngine); LocalDate appValue = LocalDate.now(); Date inputValue = Date.newBuilder().setDay(appValue.getDayOfMonth()).setMonth(appValue.getMonthValue()) .setYear(appValue.getYear()).build(); - Date actualValue = dateTranslationSpec.convertAppObject(appValue); + Date actualValue = dateTranslationSpec.translateAppObject(appValue); assertEquals(inputValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_DoubleTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_DoubleTranslationSpec.java similarity index 74% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_DoubleTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_DoubleTranslationSpec.java index d6b8a60..f93443c 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_DoubleTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_DoubleTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -7,7 +7,7 @@ import com.google.protobuf.DoubleValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); DoubleTranslationSpec doubleTranslationSpec = new DoubleTranslationSpec(); - doubleTranslationSpec.init(protobufTranslationEngine); + doubleTranslationSpec.init(protobufTaskitEngine); Double expectedValue = 100.0; DoubleValue inputValue = DoubleValue.of(expectedValue); - Double actualValue = doubleTranslationSpec.convertInputObject(inputValue); + Double actualValue = doubleTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +39,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); DoubleTranslationSpec doubleTranslationSpec = new DoubleTranslationSpec(); - doubleTranslationSpec.init(protobufTranslationEngine); + doubleTranslationSpec.init(protobufTaskitEngine); Double appValue = 100.0; DoubleValue expectedValue = DoubleValue.of(appValue); - DoubleValue actualValue = doubleTranslationSpec.convertAppObject(appValue); + DoubleValue actualValue = doubleTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_EnumTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_EnumTranslationSpec.java similarity index 74% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_EnumTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_EnumTranslationSpec.java index b9c8c3e..32e0770 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_EnumTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_EnumTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -8,11 +8,11 @@ import com.google.protobuf.BoolValue; -import gov.hhs.aspr.ms.taskit.core.testsupport.testobject.TestAppEnum; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; -import gov.hhs.aspr.ms.taskit.protobuf.input.WrapperEnumValue; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.input.TestInputEnum; -import gov.hhs.aspr.ms.taskit.protobuf.testsupport.testobject.translationSpecs.TestProtobufEnumTranslationSpec; +import gov.hhs.aspr.ms.taskit.core.testsupport.objects.TestAppEnum; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; +import gov.hhs.aspr.ms.taskit.protobuf.objects.WrapperEnumValue; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.objects.TestInputEnum; +import gov.hhs.aspr.ms.taskit.protobuf.testsupport.translation.specs.TestProtobufEnumTranslationSpec; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -28,18 +28,18 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() .addTranslationSpec(new TestProtobufEnumTranslationSpec()).build(); EnumTranslationSpec enumTranslationSpec = new EnumTranslationSpec(); - enumTranslationSpec.init(protobufTranslationEngine); + enumTranslationSpec.init(protobufTaskitEngine); TestAppEnum expectedValue = TestAppEnum.TEST1; WrapperEnumValue inputValue = WrapperEnumValue.newBuilder() .setEnumTypeUrl(TestInputEnum.TEST1.getDescriptorForType().getFullName()) .setValue(TestInputEnum.TEST1.name()).build(); - TestAppEnum actualValue = (TestAppEnum) enumTranslationSpec.convertInputObject(inputValue); + TestAppEnum actualValue = (TestAppEnum) enumTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); @@ -50,25 +50,25 @@ public void testConvertInputObject() { .setEnumTypeUrl(BoolValue.getDefaultInstance().getDescriptorForType().getFullName()) .setValue(TestInputEnum.TEST1.name()).build(); - enumTranslationSpec.convertInputObject(badInputValue); + enumTranslationSpec.translateInputObject(badInputValue); }); } @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder() + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder() .addTranslationSpec(new TestProtobufEnumTranslationSpec()).build(); EnumTranslationSpec enumTranslationSpec = new EnumTranslationSpec(); - enumTranslationSpec.init(protobufTranslationEngine); + enumTranslationSpec.init(protobufTaskitEngine); TestAppEnum appValue = TestAppEnum.TEST2; WrapperEnumValue expectedValue = WrapperEnumValue.newBuilder() .setEnumTypeUrl(TestInputEnum.TEST2.getDescriptorForType().getFullName()) .setValue(TestInputEnum.TEST2.name()).build(); - WrapperEnumValue actualValue = enumTranslationSpec.convertAppObject(appValue); + WrapperEnumValue actualValue = enumTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_FloatTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_FloatTranslationSpec.java similarity index 74% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_FloatTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_FloatTranslationSpec.java index 3303d08..2db7d3d 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_FloatTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_FloatTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -7,7 +7,7 @@ import com.google.protobuf.FloatValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); FloatTranslationSpec floatTranslationSpec = new FloatTranslationSpec(); - floatTranslationSpec.init(protobufTranslationEngine); + floatTranslationSpec.init(protobufTaskitEngine); Float expectedValue = 10.0f; FloatValue inputValue = FloatValue.of(expectedValue); - Float actualValue = floatTranslationSpec.convertInputObject(inputValue); + Float actualValue = floatTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +39,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); FloatTranslationSpec floatTranslationSpec = new FloatTranslationSpec(); - floatTranslationSpec.init(protobufTranslationEngine); + floatTranslationSpec.init(protobufTaskitEngine); Float appValue = 10.01f; FloatValue expectedValue = FloatValue.of(appValue); - FloatValue actualValue = floatTranslationSpec.convertAppObject(appValue); + FloatValue actualValue = floatTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_IntegerTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_IntegerTranslationSpec.java similarity index 74% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_IntegerTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_IntegerTranslationSpec.java index 3fa9f00..7c9827d 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_IntegerTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_IntegerTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -7,7 +7,7 @@ import com.google.protobuf.Int32Value; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); IntegerTranslationSpec integerTranslationSpec = new IntegerTranslationSpec(); - integerTranslationSpec.init(protobufTranslationEngine); + integerTranslationSpec.init(protobufTaskitEngine); Integer expectedValue = 10; Int32Value inputValue = Int32Value.of(expectedValue); - Integer actualValue = integerTranslationSpec.convertInputObject(inputValue); + Integer actualValue = integerTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +39,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); IntegerTranslationSpec integerTranslationSpec = new IntegerTranslationSpec(); - integerTranslationSpec.init(protobufTranslationEngine); + integerTranslationSpec.init(protobufTaskitEngine); Integer appValue = 10; Int32Value expectedValue = Int32Value.of(appValue); - Int32Value actualValue = integerTranslationSpec.convertAppObject(appValue); + Int32Value actualValue = integerTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_LongTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_LongTranslationSpec.java similarity index 74% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_LongTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_LongTranslationSpec.java index 664e18a..3c9dee1 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_LongTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_LongTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -7,7 +7,7 @@ import com.google.protobuf.Int64Value; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); LongTranslationSpec longTranslationSpec = new LongTranslationSpec(); - longTranslationSpec.init(protobufTranslationEngine); + longTranslationSpec.init(protobufTaskitEngine); Long expectedValue = 100L; Int64Value inputValue = Int64Value.of(expectedValue); - Long actualValue = longTranslationSpec.convertInputObject(inputValue); + Long actualValue = longTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +39,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); LongTranslationSpec longTranslationSpec = new LongTranslationSpec(); - longTranslationSpec.init(protobufTranslationEngine); + longTranslationSpec.init(protobufTaskitEngine); Long appValue = 1000L; Int64Value expectedValue = Int64Value.of(appValue); - Int64Value actualValue = longTranslationSpec.convertAppObject(appValue); + Int64Value actualValue = longTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_StringTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_StringTranslationSpec.java similarity index 75% rename from protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_StringTranslationSpec.java rename to protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_StringTranslationSpec.java index 7645118..40d83d3 100644 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_StringTranslationSpec.java +++ b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translation/specs/AT_StringTranslationSpec.java @@ -1,4 +1,4 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; +package gov.hhs.aspr.ms.taskit.protobuf.translation.specs; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -7,7 +7,7 @@ import com.google.protobuf.StringValue; -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; +import gov.hhs.aspr.ms.taskit.protobuf.engine.ProtobufJsonTaskitEngine; import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; @@ -23,15 +23,15 @@ public void testConstructor() { @Test @UnitTestForCoverage public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); StringTranslationSpec stringTranslationSpec = new StringTranslationSpec(); - stringTranslationSpec.init(protobufTranslationEngine); + stringTranslationSpec.init(protobufTaskitEngine); String expectedValue = "testString"; StringValue inputValue = StringValue.of(expectedValue); - String actualValue = stringTranslationSpec.convertInputObject(inputValue); + String actualValue = stringTranslationSpec.translateInputObject(inputValue); assertEquals(expectedValue, actualValue); } @@ -39,15 +39,15 @@ public void testConvertInputObject() { @Test @UnitTestForCoverage public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); + ProtobufJsonTaskitEngine protobufTaskitEngine = ProtobufJsonTaskitEngine.builder().build(); StringTranslationSpec stringTranslationSpec = new StringTranslationSpec(); - stringTranslationSpec.init(protobufTranslationEngine); + stringTranslationSpec.init(protobufTaskitEngine); String appValue = "testString"; StringValue expectedValue = StringValue.of(appValue); - StringValue actualValue = stringTranslationSpec.convertAppObject(appValue); + StringValue actualValue = stringTranslationSpec.translateAppObject(appValue); assertEquals(expectedValue, actualValue); } diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_UIntegerTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_UIntegerTranslationSpec.java deleted file mode 100644 index d53b375..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_UIntegerTranslationSpec.java +++ /dev/null @@ -1,70 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import org.junit.jupiter.api.Test; - -import com.google.protobuf.UInt32Value; - -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; -import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; -import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; - -public class AT_UIntegerTranslationSpec { - - @Test - @UnitTestConstructor(target = UIntegerTranslationSpec.class, args = {}) - public void testConstructor() { - assertNotNull(new UIntegerTranslationSpec()); - } - - @Test - @UnitTestForCoverage - public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - UIntegerTranslationSpec uIntegerTranslationSpec = new UIntegerTranslationSpec(); - uIntegerTranslationSpec.init(protobufTranslationEngine); - - Integer expectedValue = 10; - UInt32Value inputValue = UInt32Value.of(expectedValue); - - Integer actualValue = uIntegerTranslationSpec.convertInputObject(inputValue); - - assertEquals(expectedValue, actualValue); - } - - @Test - @UnitTestForCoverage - public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - UIntegerTranslationSpec uIntegerTranslationSpec = new UIntegerTranslationSpec(); - uIntegerTranslationSpec.init(protobufTranslationEngine); - - Integer appValue = 100; - UInt32Value expectedValue = UInt32Value.of(appValue); - - UInt32Value actualValue = uIntegerTranslationSpec.convertAppObject(appValue); - - assertEquals(expectedValue, actualValue); - } - - @Test - @UnitTestMethod(target = UIntegerTranslationSpec.class, name = "getAppObjectClass", args = {}) - public void testGetAppObjectClass() { - UIntegerTranslationSpec uIntegerTranslationSpec = new UIntegerTranslationSpec(); - - assertEquals(Integer.class, uIntegerTranslationSpec.getAppObjectClass()); - } - - @Test - @UnitTestMethod(target = UIntegerTranslationSpec.class, name = "getInputObjectClass", args = {}) - public void testGetInputObjectClass() { - UIntegerTranslationSpec uIntegerTranslationSpec = new UIntegerTranslationSpec(); - - assertEquals(UInt32Value.class, uIntegerTranslationSpec.getInputObjectClass()); - } -} \ No newline at end of file diff --git a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_ULongTranslationSpec.java b/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_ULongTranslationSpec.java deleted file mode 100644 index 750d04b..0000000 --- a/protobuf/src/test/java/gov/hhs/aspr/ms/taskit/protobuf/translationSpecs/AT_ULongTranslationSpec.java +++ /dev/null @@ -1,70 +0,0 @@ -package gov.hhs.aspr.ms.taskit.protobuf.translationSpecs; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; - -import org.junit.jupiter.api.Test; - -import com.google.protobuf.UInt64Value; - -import gov.hhs.aspr.ms.taskit.protobuf.ProtobufTranslationEngine; -import gov.hhs.aspr.ms.util.annotations.UnitTestConstructor; -import gov.hhs.aspr.ms.util.annotations.UnitTestForCoverage; -import gov.hhs.aspr.ms.util.annotations.UnitTestMethod; - -public class AT_ULongTranslationSpec { - - @Test - @UnitTestConstructor(target = ULongTranslationSpec.class, args = {}) - public void testConstructor() { - assertNotNull(new ULongTranslationSpec()); - } - - @Test - @UnitTestForCoverage - public void testConvertInputObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - ULongTranslationSpec booleanTranslationSpec = new ULongTranslationSpec(); - booleanTranslationSpec.init(protobufTranslationEngine); - - Long expectedValue = 100L; - UInt64Value inputValue = UInt64Value.of(expectedValue); - - Long actualValue = booleanTranslationSpec.convertInputObject(inputValue); - - assertEquals(expectedValue, actualValue); - } - - @Test - @UnitTestForCoverage - public void testConvertAppObject() { - ProtobufTranslationEngine protobufTranslationEngine = ProtobufTranslationEngine.builder().build(); - - ULongTranslationSpec booleanTranslationSpec = new ULongTranslationSpec(); - booleanTranslationSpec.init(protobufTranslationEngine); - - Long appValue = 100L; - UInt64Value expectedValue = UInt64Value.of(appValue); - - UInt64Value actualValue = booleanTranslationSpec.convertAppObject(appValue); - - assertEquals(expectedValue, actualValue); - } - - @Test - @UnitTestMethod(target = ULongTranslationSpec.class, name = "getAppObjectClass", args = {}) - public void testGetAppObjectClass() { - ULongTranslationSpec booleanTranslationSpec = new ULongTranslationSpec(); - - assertEquals(Long.class, booleanTranslationSpec.getAppObjectClass()); - } - - @Test - @UnitTestMethod(target = ULongTranslationSpec.class, name = "getInputObjectClass", args = {}) - public void testGetInputObjectClass() { - ULongTranslationSpec booleanTranslationSpec = new ULongTranslationSpec(); - - assertEquals(UInt64Value.class, booleanTranslationSpec.getInputObjectClass()); - } -}