From fc1413ed86e62599c5dcec5ef7c54ec9dc24c60c Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Mon, 11 Nov 2024 11:06:38 -0500 Subject: [PATCH 01/20] Added missing Javadocs. --- .../core/MetaschemaJavaVersion.java | 17 ++++++++------- .../core/model/MetaschemaVersion.java | 17 ++++++++------- .../validation/XmlSchemaContentValidator.java | 21 +++++++++---------- .../nist/secauto/metaschema/cli/CLITest.java | 6 ++++-- .../AbstractSchemaGeneratorTestSuite.java | 3 +-- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java index c81c8f95e..e19f020f2 100644 --- a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java +++ b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java @@ -3,15 +3,18 @@ import gov.nist.secauto.metaschema.core.util.IVersionInfo; +/** + * Provides version information for this library. + */ public class MetaschemaJavaVersion implements IVersionInfo { - public static final String NAME = "metaschema-java"; - public static final String VERSION = "${project.version}"; - public static final String BUILD_TIMESTAMP = "${timestamp}"; - public static final String COMMIT = "@git.commit.id.abbrev@"; - public static final String BRANCH = "@git.branch@"; - public static final String CLOSEST_TAG = "@git.closest.tag.name@"; - public static final String ORIGIN = "@git.remote.origin.url@"; + private static final String NAME = "metaschema-java"; + private static final String VERSION = "${project.version}"; + private static final String BUILD_TIMESTAMP = "${timestamp}"; + private static final String COMMIT = "@git.commit.id.abbrev@"; + private static final String BRANCH = "@git.branch@"; + private static final String CLOSEST_TAG = "@git.closest.tag.name@"; + private static final String ORIGIN = "@git.remote.origin.url@"; @Override public String getName() { diff --git a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java index a6bb77c6c..8441ecb81 100644 --- a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java +++ b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java @@ -4,15 +4,18 @@ import gov.nist.secauto.metaschema.core.util.IVersionInfo; +/** + * Provides version information for the underlying Metaschema implementation used by this library. + */ public class MetaschemaVersion implements IVersionInfo { - public static final String NAME = "metaschema"; - public static final String BUILD_VERSION = "${project.version}"; - public static final String BUILD_TIMESTAMP = "${timestamp}"; - public static final String COMMIT = "@metaschema-git.commit.id.abbrev@"; - public static final String BRANCH = "@metaschema-git.branch@"; - public static final String CLOSEST_TAG = "@metaschema-git.closest.tag.name@"; - public static final String ORIGIN = "@metaschema-git.remote.origin.url@"; + private static final String NAME = "metaschema"; + private static final String BUILD_VERSION = "${project.version}"; + private static final String BUILD_TIMESTAMP = "${timestamp}"; + private static final String COMMIT = "@metaschema-git.commit.id.abbrev@"; + private static final String BRANCH = "@metaschema-git.branch@"; + private static final String CLOSEST_TAG = "@metaschema-git.closest.tag.name@"; + private static final String ORIGIN = "@metaschema-git.remote.origin.url@"; @Override public String getName() { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/validation/XmlSchemaContentValidator.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/validation/XmlSchemaContentValidator.java index 7558e2d4b..9966a45f3 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/validation/XmlSchemaContentValidator.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/validation/XmlSchemaContentValidator.java @@ -39,18 +39,17 @@ public class XmlSchemaContentValidator @SuppressWarnings("null") @NonNull - private static Schema toSchema(@NonNull List schemaSources) throws SAXException { + private static Schema toSchema(@NonNull List schemaSources) throws IOException { SchemaFactory schemafactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); // schemafactory.setResourceResolver(new ClasspathResourceResolver()); - Schema retval; - if (schemaSources.isEmpty()) { - retval = schemafactory.newSchema(); - } else { - retval = schemafactory.newSchema(schemaSources.toArray(new Source[0])); - } - // TODO verify source input streams are closed - return retval; + try { + return schemaSources.isEmpty() + ? schemafactory.newSchema() + : schemafactory.newSchema(schemaSources.toArray(new Source[0])); + } catch (SAXException ex) { + throw new IOException(ex); + } } /** @@ -58,10 +57,10 @@ private static Schema toSchema(@NonNull List schemaSources) th * * @param schemaSources * the XML schemas to use for validation - * @throws SAXException + * @throws IOException * if an error occurred while parsing the provided XML schemas */ - public XmlSchemaContentValidator(@Owning @NonNull List schemaSources) throws SAXException { + public XmlSchemaContentValidator(@Owning @NonNull List schemaSources) throws IOException { this(toSchema(ObjectUtils.requireNonNull(schemaSources, "schemaSources"))); } diff --git a/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java b/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java index a8bb95add..c4d70aca3 100644 --- a/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java +++ b/metaschema-cli/src/test/java/gov/nist/secauto/metaschema/cli/CLITest.java @@ -215,8 +215,10 @@ void testValidateContent() { .contains("expect-default-non-zero: Expect constraint '. > 0' did not match the data", "expect-custom-non-zero: No default message, custom error message for expect-custom-non-zero constraint.", "matches-default-regex-letters-only: Value '1' did not match the pattern", - "matches-custom-regex-letters-only: No default message, custom error message for matches-custom-regex-letters-only constraint.", - "cardinality-default-two-minimum: The cardinality '1' is below the required minimum '2' for items matching", + "matches-custom-regex-letters-only: No default message, custom error message for" + + " matches-custom-regex-letters-only constraint.", + "cardinality-default-two-minimum: The cardinality '1' is below the required minimum '2' for items" + + " matching", "index-items-default: Index 'index-items-default' has duplicate key for items", "index-items-custom: No default message, custom error message for index-item-custom.", "is-unique-default: Unique constraint violation at paths", diff --git a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java index 1b082e784..59c6de450 100644 --- a/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java +++ b/schemagen/src/test/java/gov/nist/secauto/metaschema/schemagen/AbstractSchemaGeneratorTestSuite.java @@ -26,7 +26,6 @@ import gov.nist.secauto.metaschema.schemagen.xml.XmlSchemaGenerator; import org.junit.platform.commons.JUnitException; -import org.xml.sax.SAXException; import java.io.IOException; import java.io.InputStream; @@ -123,7 +122,7 @@ public abstract class AbstractSchemaGeneratorTestSuite = new StreamSource(schemaResource.openStream(), schemaResource.toString()); List schemaSources = Collections.singletonList(source); return new XmlSchemaContentValidator(schemaSources); - } catch (IOException | SAXException ex) { + } catch (IOException ex) { throw new IllegalStateException(ex); } }; From d73da15552830df3e859a3a95f31ffa6cf2b1542 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Tue, 12 Nov 2024 09:08:06 -0500 Subject: [PATCH 02/20] Refactored data type and atomic item implementations to move casting operations to the atomic item implementations. This creates a cleaner isolation between the type adapters and Metapath items. --- .../core/model/MetaschemaVersion.java | 2 +- .../AbstractCustomJavaDataTypeAdapter.java | 1 - .../datatype/AbstractDataTypeAdapter.java | 86 ++++++------- .../core/datatype/IDataTypeAdapter.java | 27 ++-- .../adapter/AbstractIntegerAdapter.java | 6 +- .../core/datatype/adapter/Base64Adapter.java | 11 +- .../core/datatype/adapter/BooleanAdapter.java | 57 --------- .../core/datatype/adapter/DateAdapter.java | 58 +++------ .../datatype/adapter/DateTimeAdapter.java | 55 +++----- .../adapter/DateTimeWithTZAdapter.java | 5 + .../datatype/adapter/DateWithTZAdapter.java | 5 + .../core/datatype/adapter/DayTimeAdapter.java | 5 + .../core/datatype/adapter/DecimalAdapter.java | 28 +---- .../datatype/adapter/EmailAddressAdapter.java | 5 + .../datatype/adapter/HostnameAdapter.java | 7 +- .../datatype/adapter/IPv4AddressAdapter.java | 5 + .../datatype/adapter/IPv6AddressAdapter.java | 5 + .../core/datatype/adapter/IntegerAdapter.java | 22 +--- .../adapter/MetaschemaDataTypeProvider.java | 118 +++++++++++++++++- .../core/datatype/adapter/NcNameAdapter.java | 5 + .../adapter/NonNegativeIntegerAdapter.java | 5 + .../adapter/PositiveIntegerAdapter.java | 5 + .../core/datatype/adapter/StringAdapter.java | 5 + .../core/datatype/adapter/TokenAdapter.java | 5 + .../core/datatype/adapter/UriAdapter.java | 5 + .../datatype/adapter/UriReferenceAdapter.java | 5 + .../core/datatype/adapter/UuidAdapter.java | 8 +- .../datatype/adapter/YearMonthAdapter.java | 5 + .../markup/AbstractMarkupAdapter.java | 8 +- .../datatype/markup/AbstractMarkupString.java | 6 + .../core/datatype/markup/IMarkupString.java | 22 +--- .../markup/MarkupDataTypeProvider.java | 10 ++ .../core/datatype/markup/MarkupLine.java | 5 + .../core/datatype/markup/MarkupMultiline.java | 5 + .../function/ComparisonFunctions.java | 2 +- .../core/metapath/function/FunctionUtils.java | 8 +- .../metapath/function/library/FnCeiling.java | 4 +- .../metapath/function/library/FnMinMax.java | 19 ++- .../item/atomic/AbstractAnyAtomicItem.java | 20 +-- .../item/atomic/AbstractAtomicItemBase.java | 33 +++++ .../metapath/item/atomic/IAnyAtomicItem.java | 21 ++-- .../metapath/item/atomic/IAnyUriItem.java | 37 ++++-- .../item/atomic/IBase64BinaryItem.java | 24 +++- .../metapath/item/atomic/IBooleanItem.java | 44 +++++-- .../core/metapath/item/atomic/IDateItem.java | 36 +++++- .../metapath/item/atomic/IDateTimeItem.java | 30 ++++- .../item/atomic/IDayTimeDurationItem.java | 24 +++- .../metapath/item/atomic/IDecimalItem.java | 53 ++++++-- .../metapath/item/atomic/IDurationItem.java | 15 ++- .../item/atomic/IEmailAddressItem.java | 22 +++- .../metapath/item/atomic/IHostnameItem.java | 20 ++- .../metapath/item/atomic/IIPAddressItem.java | 33 +++++ .../item/atomic/IIPv4AddressItem.java | 35 +++++- .../item/atomic/IIPv6AddressItem.java | 35 +++++- .../metapath/item/atomic/IIntegerItem.java | 64 +++++++--- .../metapath/item/atomic/IMarkupItem.java | 28 ++++- .../metapath/item/atomic/INcNameItem.java | 20 ++- .../item/atomic/INonNegativeIntegerItem.java | 42 +++++-- .../metapath/item/atomic/INumericItem.java | 14 ++- .../item/atomic/IPositiveIntegerItem.java | 32 +++-- .../metapath/item/atomic/IStringItem.java | 24 +++- .../metapath/item/atomic/ITemporalItem.java | 3 + .../core/metapath/item/atomic/ITokenItem.java | 21 +++- .../item/atomic/IUntypedAtomicItem.java | 3 + .../item/atomic/IUriReferenceItem.java | 39 +++++- .../core/metapath/item/atomic/IUuidItem.java | 36 +++++- .../item/atomic/IYearMonthDurationItem.java | 26 +++- .../atomic/{ => impl}/AbstractDateItem.java | 19 ++- .../{ => impl}/AbstractDateTimeItem.java | 19 ++- .../{ => impl}/AbstractDecimalItem.java | 15 ++- .../{ => impl}/AbstractIntegerItem.java | 10 +- .../atomic/{ => impl}/AbstractStringItem.java | 9 +- .../{ => impl}/AbstractTemporalItem.java | 6 +- .../atomic/{ => impl}/AbstractUriItem.java | 10 +- .../atomic/{ => impl}/AnyUriItemImpl.java | 13 +- .../{ => impl}/Base64BinaryItemImpl.java | 22 +++- .../atomic/{ => impl}/BooleanItemImpl.java | 30 +++-- .../DateTimeWithTimeZoneItemImpl.java | 14 ++- .../DateTimeWithoutTimeZoneItemImpl.java | 14 ++- .../{ => impl}/DateWithTimeZoneItemImpl.java | 14 ++- .../DateWithoutTimeZoneItemImpl.java | 15 ++- .../{ => impl}/DayTimeDurationItemImpl.java | 22 +++- .../atomic/{ => impl}/DecimalItemImpl.java | 33 ++++- .../{ => impl}/EmailAddressItemImpl.java | 15 ++- .../atomic/{ => impl}/HostnameItemImpl.java | 14 ++- .../{ => impl}/IPv4AddressItemImpl.java | 16 ++- .../{ => impl}/IPv6AddressItemImpl.java | 16 ++- .../atomic/{ => impl}/IntegerItemImpl.java | 15 ++- .../atomic/{ => impl}/MarkupLineItemImpl.java | 16 ++- .../{ => impl}/MarkupMultiLineItemImpl.java | 16 ++- .../atomic/{ => impl}/NcNameItemImpl.java | 15 ++- .../NonNegativeIntegerItemImpl.java | 18 ++- .../{ => impl}/PositiveIntegerItemImpl.java | 18 ++- .../atomic/{ => impl}/StringItemImpl.java | 13 +- .../item/atomic/{ => impl}/TokenItemImpl.java | 15 ++- .../{ => impl}/UriReferenceItemImpl.java | 15 ++- .../item/atomic/{ => impl}/UuidItemImpl.java | 22 +++- .../{ => impl}/YearMonthDurationItemImpl.java | 22 +++- .../function/library/FnCeilingTest.java | 5 +- 99 files changed, 1516 insertions(+), 479 deletions(-) create mode 100644 core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAtomicItemBase.java rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractDateItem.java (56%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractDateTimeItem.java (55%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractDecimalItem.java (66%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractIntegerItem.java (79%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractStringItem.java (82%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractTemporalItem.java (81%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AbstractUriItem.java (73%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/AnyUriItemImpl.java (62%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/Base64BinaryItemImpl.java (66%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/BooleanItemImpl.java (66%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/DateTimeWithTimeZoneItemImpl.java (65%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/DateTimeWithoutTimeZoneItemImpl.java (66%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/DateWithTimeZoneItemImpl.java (65%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/DateWithoutTimeZoneItemImpl.java (65%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/DayTimeDurationItemImpl.java (65%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/DecimalItemImpl.java (57%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/EmailAddressItemImpl.java (57%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/HostnameItemImpl.java (57%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/IPv4AddressItemImpl.java (58%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/IPv6AddressItemImpl.java (58%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/IntegerItemImpl.java (56%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/MarkupLineItemImpl.java (58%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/MarkupMultiLineItemImpl.java (59%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/NcNameItemImpl.java (59%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/NonNegativeIntegerItemImpl.java (53%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/PositiveIntegerItemImpl.java (53%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/StringItemImpl.java (61%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/TokenItemImpl.java (57%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/UriReferenceItemImpl.java (58%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/UuidItemImpl.java (70%) rename core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/{ => impl}/YearMonthDurationItemImpl.java (66%) diff --git a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java index 8441ecb81..942731fda 100644 --- a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java +++ b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/model/MetaschemaVersion.java @@ -24,7 +24,7 @@ public String getName() { @Override public String getVersion() { - return CLOSEST_TAG; + return BUILD_VERSION; } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractCustomJavaDataTypeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractCustomJavaDataTypeAdapter.java index 409cf786a..b5e81cdc9 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractCustomJavaDataTypeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractCustomJavaDataTypeAdapter.java @@ -43,5 +43,4 @@ public TYPE copy(Object obj) { // method. return ((TYPE) obj).copy(); } - } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractDataTypeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractDataTypeAdapter.java index 8f6fd6178..16ddfb969 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractDataTypeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/AbstractDataTypeAdapter.java @@ -8,7 +8,6 @@ import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; -import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; import gov.nist.secauto.metaschema.core.model.util.JsonUtil; import gov.nist.secauto.metaschema.core.model.util.XmlEventUtil; @@ -197,46 +196,47 @@ public void writeJsonValue(Object value, JsonGenerator generator) throws IOExcep @Override public abstract ITEM_TYPE newItem(Object value); - - @SuppressWarnings("unchecked") - @Override - public ITEM_TYPE cast(IAnyAtomicItem item) { - if (item == null) { - throw new InvalidValueForCastFunctionException("item is null"); - } - return getItemClass().isAssignableFrom(item.getClass()) - ? (ITEM_TYPE) item - : castInternal(item); - } - - /** - * Attempt to cast the provided item to this adapter's item type. - *

- * The default implementation of this will attempt to parse the provided item as - * a string using the {@link #parse(String)} method. If this behavior is - * undesirable, then a subclass should override this method. - * - * @param item - * the item to cast - * @return the item casted to this adapter's item type - * @throws InvalidValueForCastFunctionException - * if the casting of the item is not possible because the item - * represents an invalid value for this adapter's item type - */ - @NonNull - protected ITEM_TYPE castInternal(@NonNull IAnyAtomicItem item) { - // try string based casting as a fallback - String itemString; - try { - itemString = item.asString(); - TYPE value = parse(itemString); - return newItem(value); - } catch (IllegalArgumentException | IllegalStateException ex) { - throw new InvalidValueForCastFunctionException( - String.format("The value '%s' is not compatible with the type '%s'", - item.getValue(), - getItemClass().getName()), - ex); - } - } + // + // @SuppressWarnings("unchecked") + // @Override + // public ITEM_TYPE cast(IAnyAtomicItem item) { + // if (item == null) { + // throw new InvalidValueForCastFunctionException("item is null"); + // } + // return getItemClass().isAssignableFrom(item.getClass()) + // ? (ITEM_TYPE) item + // : castInternal(item); + // } + // + // /** + // * Attempt to cast the provided item to this adapter's item type. + // *

+ // * The default implementation of this will attempt to parse the provided item + // as + // * a string using the {@link #parse(String)} method. If this behavior is + // * undesirable, then a subclass should override this method. + // * + // * @param item + // * the item to cast + // * @return the item casted to this adapter's item type + // * @throws InvalidValueForCastFunctionException + // * if the casting of the item is not possible because the item + // * represents an invalid value for this adapter's item type + // */ + // @NonNull + // protected ITEM_TYPE castInternal(@NonNull IAnyAtomicItem item) { + // // try string based casting as a fallback + // String itemString; + // try { + // itemString = item.asString(); + // TYPE value = parse(itemString); + // return newItem(value); + // } catch (IllegalArgumentException | IllegalStateException ex) { + // throw new InvalidValueForCastFunctionException( + // String.format("The value '%s' is not compatible with the type '%s'", + // item.getValue(), + // getItemClass().getName()), + // ex); + // } + // } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/IDataTypeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/IDataTypeAdapter.java index 83a8183e9..6c3361281 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/IDataTypeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/IDataTypeAdapter.java @@ -9,7 +9,6 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; -import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; @@ -142,19 +141,19 @@ default boolean isAtomic() { // TODO: move to IAnyAtomicItem @NonNull IAnyAtomicItem newItem(@NonNull Object value); - - /** - * Cast the provided item to an item of this type, if possible. - * - * @param item - * the atomic item to cast - * @return an atomic item of this type - * @throws InvalidValueForCastFunctionException - * if the provided item type cannot be cast to this item type - */ - // TODO: move to IAnyAtomicItem - @NonNull - IAnyAtomicItem cast(IAnyAtomicItem item); + // + // /** + // * Cast the provided item to an item of this type, if possible. + // * + // * @param item + // * the atomic item to cast + // * @return an atomic item of this type + // * @throws InvalidValueForCastFunctionException + // * if the provided item type cannot be cast to this item type + // */ + // // TODO: move to IAnyAtomicItem + // @NonNull + // IAnyAtomicItem cast(IAnyAtomicItem item); /** * Determines if adapter can parse the next element. The next element's diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/AbstractIntegerAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/AbstractIntegerAdapter.java index 7dd52be02..721fcfadc 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/AbstractIntegerAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/AbstractIntegerAdapter.java @@ -39,7 +39,11 @@ public JsonFormatTypes getJsonRawType() { @Override public BigInteger parse(String value) { - return new BigInteger(value); + try { + return new BigInteger(value); + } catch (NumberFormatException ex) { + throw new IllegalArgumentException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java index 7bcef4b6f..6b5d8f4d1 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java @@ -20,6 +20,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema base64 + * data type. + */ public class Base64Adapter extends AbstractDataTypeAdapter { @NonNull @@ -43,12 +48,11 @@ public JsonFormatTypes getJsonRawType() { return JsonFormatTypes.STRING; } - @SuppressWarnings("null") @Override public ByteBuffer parse(String value) { Base64.Decoder decoder = Base64.getDecoder(); byte[] result = decoder.decode(value); - return ByteBuffer.wrap(result); + return ObjectUtils.notNull(ByteBuffer.wrap(result)); } @Override @@ -62,11 +66,10 @@ public ByteBuffer copy(Object obj) { return clone; } - @SuppressWarnings("null") @Override public String asString(Object value) { Base64.Encoder encoder = Base64.getEncoder(); - return encoder.encodeToString(((ByteBuffer) value).array()); + return ObjectUtils.notNull(encoder.encodeToString(((ByteBuffer) value).array())); } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/BooleanAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/BooleanAdapter.java index b0336a405..f39cd0363 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/BooleanAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/BooleanAdapter.java @@ -11,11 +11,7 @@ import gov.nist.secauto.metaschema.core.datatype.AbstractDataTypeAdapter; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; -import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.INumericItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.io.IOException; @@ -92,57 +88,4 @@ public IBooleanItem newItem(Object value) { return IBooleanItem.valueOf(item); } - @Override - protected IBooleanItem castInternal(@NonNull IAnyAtomicItem item) { - IBooleanItem retval; - if (item instanceof INumericItem) { - retval = castToBoolean((INumericItem) item); - } else if (item instanceof IStringItem) { - retval = castToBoolean((IStringItem) item); - } else { - try { - retval = castToBoolean(item.asStringItem()); - } catch (IllegalStateException ex) { - throw new InvalidValueForCastFunctionException(ex.getLocalizedMessage(), ex); - } - } - return retval; - } - - /** - * Cast the provided numeric value to a boolean. Any non-zero value will be - * {@code true}, or {@code false} otherwise. - * - * @param item - * the item to cast - * @return {@code true} if the item value is non-zero, or {@code false} - * otherwise - */ - @NonNull - protected IBooleanItem castToBoolean(@NonNull INumericItem item) { - return IBooleanItem.valueOf(item.toEffectiveBoolean()); - } - - /** - * If the string is a numeric value, treat it as so. Otherwise parse the value - * as a boolean string. - * - * @param item - * the item to cast - * @return the effective boolean value of the string - * @throws InvalidValueForCastFunctionException - * if the provided item cannot be cast to a boolean value by any means - */ - @NonNull - protected IBooleanItem castToBoolean(@NonNull IStringItem item) { - IBooleanItem retval; - try { - INumericItem numeric = INumericItem.cast(item); - retval = castToBoolean(numeric); - } catch (InvalidValueForCastFunctionException ex) { - retval = super.castInternal(item); - } - return retval; - } - } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java index d8191f8be..4498f11f4 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java @@ -10,12 +10,7 @@ import gov.nist.secauto.metaschema.core.datatype.AbstractCustomJavaDataTypeAdapter; import gov.nist.secauto.metaschema.core.datatype.object.Date; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; -import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateTimeItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IUntypedAtomicItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.time.LocalDate; @@ -32,18 +27,25 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema date + * data type. + */ public class DateAdapter extends AbstractCustomJavaDataTypeAdapter { @NonNull private static final List NAMES = ObjectUtils.notNull( List.of(new QName(MetapathConstants.NS_METAPATH.toASCIIString(), "date"))); - private static final Pattern DATE_TIMEZONE = Pattern.compile("^(" - + "^(?:(?:2000|2400|2800|(?:19|2[0-9](?:0[48]|[2468][048]|[13579][26])))-02-29)" - + "|(?:(?:(?:19|2[0-9])[0-9]{2})-02-(?:0[1-9]|1[0-9]|2[0-8]))" - + "|(?:(?:(?:19|2[0-9])[0-9]{2})-(?:0[13578]|10|12)-(?:0[1-9]|[12][0-9]|3[01]))" - + "|(?:(?:(?:19|2[0-9])[0-9]{2})-(?:0[469]|11)-(?:0[1-9]|[12][0-9]|30))" - + ")" - + "(Z|[+-][0-9]{2}:[0-9]{2})?$"); + @NonNull + private static final Pattern DATE_TIMEZONE = ObjectUtils.notNull( + Pattern.compile("^(" + + "^(?:(?:2000|2400|2800|(?:19|2[0-9](?:0[48]|[2468][048]|[13579][26])))-02-29)" + + "|(?:(?:(?:19|2[0-9])[0-9]{2})-02-(?:0[1-9]|1[0-9]|2[0-8]))" + + "|(?:(?:(?:19|2[0-9])[0-9]{2})-(?:0[13578]|10|12)-(?:0[1-9]|[12][0-9]|3[01]))" + + "|(?:(?:(?:19|2[0-9])[0-9]{2})-(?:0[469]|11)-(?:0[1-9]|[12][0-9]|30))" + + ")" + + "(Z|[+-][0-9]{2}:[0-9]{2})?$")); DateAdapter() { super(Date.class); @@ -87,19 +89,9 @@ public Date parse(String value) { @Override public String asString(Object obj) { Date value = (Date) obj; - String retval; - if (value.hasTimeZone()) { - @SuppressWarnings("null") - @NonNull - String formatted = DateFormats.DATE_WITH_TZ.format(value.getValue()); - retval = formatted; - } else { - @SuppressWarnings("null") - @NonNull - String formatted = DateFormats.DATE_WITHOUT_TZ.format(value.getValue()); - retval = formatted; - } - return retval; + return ObjectUtils.notNull(value.hasTimeZone() + ? DateFormats.DATE_WITH_TZ.format(value.getValue()) + : DateFormats.DATE_WITHOUT_TZ.format(value.getValue())); } @Override @@ -112,20 +104,4 @@ public IDateItem newItem(Object value) { Date item = toValue(value); return IDateItem.valueOf(item); } - - @Override - @NonNull - protected IDateItem castInternal(@NonNull IAnyAtomicItem item) { - IDateItem retval; - if (item instanceof IDateTimeItem) { - ZonedDateTime value = ((IDateTimeItem) item).asZonedDateTime(); - retval = IDateItem.valueOf(value); - } else if (item instanceof IStringItem || item instanceof IUntypedAtomicItem) { - retval = super.castInternal(item); - } else { - throw new InvalidValueForCastFunctionException( - String.format("unsupported item type '%s'", item.getClass().getName())); - } - return retval; - } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java index 32cb0b385..5674dcf09 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java @@ -10,12 +10,7 @@ import gov.nist.secauto.metaschema.core.datatype.AbstractCustomJavaDataTypeAdapter; import gov.nist.secauto.metaschema.core.datatype.object.DateTime; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; -import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateTimeItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IUntypedAtomicItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.time.LocalDateTime; @@ -28,6 +23,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema date-time + * data type. + */ public class DateTimeAdapter extends AbstractCustomJavaDataTypeAdapter { @NonNull @@ -51,39 +51,34 @@ public JsonFormatTypes getJsonRawType() { return JsonFormatTypes.STRING; } - @SuppressWarnings("null") @Override public DateTime parse(String value) { + DateTime retval; try { - return new DateTime(ZonedDateTime.from(DateFormats.DATE_TIME_WITH_TZ.parse(value)), true); // NOPMD - readability + retval = new DateTime( + ObjectUtils.notNull(ZonedDateTime.from(DateFormats.DATE_TIME_WITH_TZ.parse(value))), + true); } catch (DateTimeParseException ex) { try { LocalDateTime dateTime = LocalDateTime.from(DateFormats.DATE_TIME_WITHOUT_TZ.parse(value)); - return new DateTime(ZonedDateTime.of(dateTime, ZoneOffset.UTC), false); + retval = new DateTime( + ObjectUtils.notNull(ZonedDateTime.of(dateTime, ZoneOffset.UTC)), + false); } catch (DateTimeParseException ex2) { IllegalArgumentException newEx = new IllegalArgumentException(ex2.getLocalizedMessage(), ex2); newEx.addSuppressed(ex); - throw newEx; // NOPMD - it's ok + throw newEx; } } + return retval; } @Override public String asString(Object obj) { DateTime value = (DateTime) obj; - String retval; - if (value.hasTimeZone()) { - @SuppressWarnings("null") - @NonNull - String formatted = DateFormats.DATE_TIME_WITH_TZ.format(value.getValue()); - retval = formatted; - } else { - @SuppressWarnings("null") - @NonNull - String formatted = DateFormats.DATE_TIME_WITHOUT_TZ.format(value.getValue()); - retval = formatted; - } - return retval; + return ObjectUtils.notNull(value.hasTimeZone() + ? DateFormats.DATE_TIME_WITH_TZ.format(value.getValue()) + : DateFormats.DATE_TIME_WITHOUT_TZ.format(value.getValue())); } @Override @@ -96,20 +91,4 @@ public IDateTimeItem newItem(Object value) { DateTime item = toValue(value); return IDateTimeItem.valueOf(item); } - - @Override - protected IDateTimeItem castInternal(@NonNull IAnyAtomicItem item) { - // TODO: bring up to spec - IDateTimeItem retval; - if (item instanceof IDateItem) { - retval = IDateTimeItem.valueOf(((IDateItem) item).asZonedDateTime()); - } else if (item instanceof IStringItem || item instanceof IUntypedAtomicItem) { - retval = super.castInternal(item); - } else { - throw new InvalidValueForCastFunctionException( - String.format("unsupported item type '%s'", item.getClass().getName())); - } - return retval; - } - } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeWithTZAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeWithTZAdapter.java index d928d0bae..3c1c0f4d9 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeWithTZAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeWithTZAdapter.java @@ -21,6 +21,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema date-time-with-timezone + * data type. + */ public class DateTimeWithTZAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateWithTZAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateWithTZAdapter.java index 5e16e7854..f309d20d7 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateWithTZAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateWithTZAdapter.java @@ -23,6 +23,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema date-with-timezone + * data type. + */ public class DateWithTZAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DayTimeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DayTimeAdapter.java index 5f9ca4348..6632ab70b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DayTimeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DayTimeAdapter.java @@ -20,6 +20,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema day-time-duration + * data type. + */ public class DayTimeAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DecimalAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DecimalAdapter.java index 52169723e..25667eb66 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DecimalAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DecimalAdapter.java @@ -10,10 +10,7 @@ import gov.nist.secauto.metaschema.core.datatype.AbstractDataTypeAdapter; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDecimalItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.INumericItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.io.IOException; @@ -25,13 +22,14 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema decimal + * data type. + */ public class DecimalAdapter extends AbstractDataTypeAdapter { - public static final MathContext MATH_CONTEXT = MathContext.DECIMAL64; - @NonNull - private static final BigDecimal DECIMAL_BOOLEAN_TRUE = new BigDecimal("1.0"); - @NonNull - private static final BigDecimal DECIMAL_BOOLEAN_FALSE = new BigDecimal("0.0"); + private static final MathContext MATH_CONTEXT = MathContext.DECIMAL64; @NonNull private static final List NAMES = ObjectUtils.notNull( List.of(new QName(MetapathConstants.NS_METAPATH.toASCIIString(), "decimal"))); @@ -80,18 +78,4 @@ public IDecimalItem newItem(Object value) { BigDecimal item = toValue(value); return IDecimalItem.valueOf(item); } - - @Override - protected IDecimalItem castInternal(@NonNull IAnyAtomicItem item) { - IDecimalItem retval; - if (item instanceof INumericItem) { - retval = newItem(((INumericItem) item).asDecimal()); - } else if (item instanceof IBooleanItem) { - boolean value = ((IBooleanItem) item).toBoolean(); - retval = newItem(value ? DECIMAL_BOOLEAN_TRUE : DECIMAL_BOOLEAN_FALSE); - } else { - retval = super.castInternal(item); - } - return retval; - } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/EmailAddressAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/EmailAddressAdapter.java index 982325aec..35b128459 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/EmailAddressAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/EmailAddressAdapter.java @@ -15,6 +15,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema email-address + * data type. + */ public class EmailAddressAdapter extends AbstractStringAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java index 51feb78d7..5014eac59 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java @@ -15,6 +15,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema hostname + * data type. + */ public class HostnameAdapter extends AbstractStringAdapter { @NonNull @@ -32,7 +37,7 @@ public List getNames() { @Override public @NonNull - Class getItemClass() { + Class getItemClass() { return IHostnameItem.class; } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv4AddressAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv4AddressAdapter.java index 123a1ab27..d62023fe5 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv4AddressAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv4AddressAdapter.java @@ -23,6 +23,11 @@ import inet.ipaddr.IncompatibleAddressException; import inet.ipaddr.ipv4.IPv4Address; +/** + * Support for the Metaschema ip-v4-address + * data type. + */ public class IPv4AddressAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv6AddressAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv6AddressAdapter.java index 324927f63..d7642d6cd 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv6AddressAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IPv6AddressAdapter.java @@ -23,6 +23,11 @@ import inet.ipaddr.IncompatibleAddressException; import inet.ipaddr.ipv6.IPv6Address; +/** + * Support for the Metaschema ip-v6-address + * data type. + */ public class IPv6AddressAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IntegerAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IntegerAdapter.java index f77e74630..b6634c120 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IntegerAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/IntegerAdapter.java @@ -6,10 +6,7 @@ package gov.nist.secauto.metaschema.core.datatype.adapter; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem; -import gov.nist.secauto.metaschema.core.metapath.item.atomic.INumericItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.math.BigInteger; @@ -19,6 +16,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema integer + * data type. + */ public class IntegerAdapter extends AbstractIntegerAdapter { @NonNull @@ -45,18 +47,4 @@ public IIntegerItem newItem(Object value) { BigInteger item = toValue(value); return IIntegerItem.valueOf(item); } - - @Override - protected IIntegerItem castInternal(@NonNull IAnyAtomicItem item) { - IIntegerItem retval; - if (item instanceof INumericItem) { - retval = newItem(((INumericItem) item).asInteger()); - } else if (item instanceof IBooleanItem) { - boolean value = ((IBooleanItem) item).toBoolean(); - retval = newItem(ObjectUtils.notNull(value ? BigInteger.ONE : BigInteger.ZERO)); - } else { - retval = super.castInternal(item); - } - return retval; - } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/MetaschemaDataTypeProvider.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/MetaschemaDataTypeProvider.java index 6969a6cd7..bb91ba4f8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/MetaschemaDataTypeProvider.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/MetaschemaDataTypeProvider.java @@ -16,55 +16,165 @@ @SuppressWarnings("PMD.CouplingBetweenObjects") public final class MetaschemaDataTypeProvider // NOPMD - Used for service initialization extends AbstractDataTypeProvider { + /** + * The Metaschema base64 + * data type instance. + */ @NonNull public static final Base64Adapter BASE64 = new Base64Adapter(); + /** + * The Metaschema boolean + * data type instance. + */ @NonNull public static final BooleanAdapter BOOLEAN = new BooleanAdapter(); + /** + * The Metaschema date + * data type instance. + */ @NonNull public static final DateAdapter DATE = new DateAdapter(); + /** + * The Metaschema date-with-timezone + * data type instance. + */ @NonNull public static final DateWithTZAdapter DATE_WITH_TZ = new DateWithTZAdapter(); + /** + * The Metaschema date-time + * data type instance. + */ @NonNull public static final DateTimeAdapter DATE_TIME = new DateTimeAdapter(); + /** + * The Metaschema date-time-with-timezone + * data type instance. + */ @NonNull public static final DateTimeWithTZAdapter DATE_TIME_WITH_TZ = new DateTimeWithTZAdapter(); + /** + * The Metaschema ip-v4-address + * data type instance. + */ @NonNull public static final IPv4AddressAdapter IP_V4_ADDRESS = new IPv4AddressAdapter(); + /** + * The Metaschema ip-v6-address + * data type instance. + */ @NonNull public static final IPv6AddressAdapter IP_V6_ADDRESS = new IPv6AddressAdapter(); + /** + * The Metaschema uri data + * type instance. + */ @NonNull public static final UriAdapter URI = new UriAdapter(); + /** + * The Metaschema uri-reference + * data type instance. + */ @NonNull public static final UriReferenceAdapter URI_REFERENCE = new UriReferenceAdapter(); + /** + * The Metaschema uuid + * data type instance. + */ @NonNull public static final UuidAdapter UUID = new UuidAdapter(); - + /** + * The Metaschema day-time-duration + * data type instance. + */ @NonNull public static final DayTimeAdapter DAY_TIME_DURATION = new DayTimeAdapter(); + /** + * The Metaschema year-month-duration + * data type instance. + */ @NonNull public static final YearMonthAdapter YEAR_MONTH_DURATION = new YearMonthAdapter(); - + /** + * The Metaschema decimal + * data type instance. + */ @NonNull public static final DecimalAdapter DECIMAL = new DecimalAdapter(); + /** + * The Metaschema integer + * data type instance. + */ @NonNull public static final IntegerAdapter INTEGER = new IntegerAdapter(); + /** + * The Metaschema non-negative-integer + * data type instance. + */ @NonNull public static final NonNegativeIntegerAdapter NON_NEGATIVE_INTEGER = new NonNegativeIntegerAdapter(); + /** + * The Metaschema positive-integer + * data type instance. + */ @NonNull public static final PositiveIntegerAdapter POSITIVE_INTEGER = new PositiveIntegerAdapter(); - + /** + * The Metaschema email-address + * data type instance. + */ @NonNull public static final EmailAddressAdapter EMAIL_ADDRESS = new EmailAddressAdapter(); + /** + * The Metaschema hostname + * data type instance. + */ @NonNull public static final HostnameAdapter HOSTNAME = new HostnameAdapter(); + /** + * The Metaschema ncname + * data type instance. + */ @Deprecated(since = "0.7.0") @NonNull public static final NcNameAdapter NCNAME = new NcNameAdapter(); + /** + * The Metaschema string + * data type instance. + */ @NonNull public static final StringAdapter STRING = new StringAdapter(); + /** + * The Metaschema token + * data type instance. + */ @NonNull public static final TokenAdapter TOKEN = new TokenAdapter(); - + /** + * The default Metaschema data type instance to use when no data type is defined + * on a field or flag. + */ @NonNull public static final StringAdapter DEFAULT_DATA_TYPE = STRING; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NcNameAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NcNameAdapter.java index 088a4d9da..143c98077 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NcNameAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NcNameAdapter.java @@ -15,6 +15,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema ncname + * data type. + */ @Deprecated(since = "0.7.0") public class NcNameAdapter extends AbstractStringAdapter { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NonNegativeIntegerAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NonNegativeIntegerAdapter.java index 15de6ff0a..9063bb00a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NonNegativeIntegerAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/NonNegativeIntegerAdapter.java @@ -16,6 +16,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema non-negative-integer + * data type. + */ public class NonNegativeIntegerAdapter extends AbstractIntegerAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/PositiveIntegerAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/PositiveIntegerAdapter.java index 22db33056..a78141ed7 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/PositiveIntegerAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/PositiveIntegerAdapter.java @@ -16,6 +16,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema positive-integer + * data type. + */ public class PositiveIntegerAdapter extends AbstractIntegerAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/StringAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/StringAdapter.java index 18b0e4d05..8c5373d74 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/StringAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/StringAdapter.java @@ -15,6 +15,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema string + * data type. + */ public class StringAdapter extends AbstractStringAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/TokenAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/TokenAdapter.java index 39091f4d5..f7d9d42a6 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/TokenAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/TokenAdapter.java @@ -15,6 +15,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema token + * data type. + */ public class TokenAdapter extends AbstractStringAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriAdapter.java index 0ffb1afcc..fbeaa5137 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriAdapter.java @@ -19,6 +19,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema uri data + * type. + */ public class UriAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriReferenceAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriReferenceAdapter.java index e51a4c6bd..92587d733 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriReferenceAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UriReferenceAdapter.java @@ -19,6 +19,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema uri-reference + * data type. + */ public class UriReferenceAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UuidAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UuidAdapter.java index 4edaface0..e62f76719 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UuidAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/UuidAdapter.java @@ -20,12 +20,18 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema uuid + * data type. + */ public class UuidAdapter extends AbstractDataTypeAdapter { @NonNull private static final List NAMES = ObjectUtils.notNull( List.of(new QName(MetapathConstants.NS_METAPATH.toASCIIString(), "uuid"))); - public static final Pattern UUID_PATTERN + @SuppressWarnings({ "unused", "PMD.UnusedPrivateField" }) + private static final Pattern UUID_PATTERN = Pattern.compile("^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[45][0-9A-Fa-f]{3}-[89ABab][0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$"); UuidAdapter() { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/YearMonthAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/YearMonthAdapter.java index 518b70ead..7f1511adf 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/YearMonthAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/YearMonthAdapter.java @@ -20,6 +20,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Support for the Metaschema year-month-duration + * data type. + */ public class YearMonthAdapter extends AbstractDataTypeAdapter { @NonNull diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupAdapter.java index e745ea7d3..b4f63bd14 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupAdapter.java @@ -24,7 +24,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public abstract class AbstractMarkupAdapter> +/** + * Provides base support for the Metaschema markup + * data types. + */ +abstract class AbstractMarkupAdapter> extends AbstractCustomJavaDataTypeAdapter { /** @@ -47,7 +52,6 @@ public boolean isXmlMixed() { return true; } - // TODO: verify that read/write methods cannot be generalized in the base class @Override public void writeXmlValue( Object value, diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupString.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupString.java index 473629e4b..36ba0cc7e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupString.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/AbstractMarkupString.java @@ -52,6 +52,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +/** + * The common base for all markup implementations. + * + * @param + * the Java type of the concrete markup implementation + */ @SuppressWarnings("PMD.CouplingBetweenObjects") public abstract class AbstractMarkupString> implements IMarkupString { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/IMarkupString.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/IMarkupString.java index a7e961c99..8e9a06479 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/IMarkupString.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/IMarkupString.java @@ -26,6 +26,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * The common interface for all markup implementations. + * + * @param + * the Java type of the concrete markup implementation + */ public interface IMarkupString> extends ICustomJavaDataType { /** @@ -51,22 +57,6 @@ public interface IMarkupString> */ boolean isEmpty(); - // /** - // * Write HTML content to the provided {@code xmlStreamWriter} using the - // provided {@code - // namespace}. - // * - // * @param writer - // * the writer - // * @param namespace - // * the XML namespace for the HTML - // * @throws XMLStreamException - // * if an error occurred while writing - // */ - // void writeHtml(@NonNull XMLStreamWriter2 writer, @NonNull String namespace) - // throws - // XMLStreamException; - /** * Get the HyperText Markup Language (HTML) representation of this markup * string. diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupDataTypeProvider.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupDataTypeProvider.java index e2836d3ba..8750f4086 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupDataTypeProvider.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupDataTypeProvider.java @@ -15,8 +15,18 @@ */ public final class MarkupDataTypeProvider extends AbstractDataTypeProvider { + /** + * The Metaschema markup-line + * data type instance. + */ @NonNull public static final MarkupLineAdapter MARKUP_LINE = new MarkupLineAdapter(); + /** + * The Metaschema markup-multiline + * data type instance. + */ @NonNull public static final MarkupMultilineAdapter MARKUP_MULTILINE = new MarkupMultilineAdapter(); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java index 605e95371..77468d545 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java @@ -24,6 +24,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Supports a data value which is a single line of markup. + *

+ * This markup can be presented as XHTML or Markdown. + */ public final class MarkupLine extends AbstractMarkupString { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupMultiline.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupMultiline.java index f84205316..08bf7afa8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupMultiline.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupMultiline.java @@ -11,6 +11,11 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Supports a data value which may be multiple lines of markup. + *

+ * This markup can be presented as XHTML or Markdown. + */ public class MarkupMultiline extends AbstractMarkupString { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java index aab9f3737..9c1854e7e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java @@ -150,7 +150,7 @@ private static IAnyAtomicItem applyGeneralComparisonCast(@NonNull IAnyAtomicItem } else if (item instanceof IDayTimeDurationItem) { retval = IYearMonthDurationItem.cast(other); } else { - retval = item.getJavaTypeAdapter().cast(other); + retval = item.castAsType(other); } return retval; } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionUtils.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionUtils.java index a968762bb..b7cb48fa6 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionUtils.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/FunctionUtils.java @@ -127,6 +127,9 @@ public static INumericItem toNumeric(@NonNull ISequence sequence, boolean req public static INumericItem toNumeric(@NonNull IItem item) { // atomize IAnyAtomicItem atomicItem = ISequence.getFirstItem(FnData.atomize(item), true); + if (atomicItem == null) { + throw new InvalidTypeMetapathException(item, "Unable to cast null item"); + } return toNumeric(atomicItem); } @@ -140,7 +143,7 @@ public static INumericItem toNumeric(@NonNull IItem item) { * if the item cannot be cast to a numeric value */ @NonNull - public static INumericItem toNumeric(@Nullable IAnyAtomicItem item) { + public static INumericItem toNumeric(@NonNull IAnyAtomicItem item) { try { return IDecimalItem.cast(item); } catch (InvalidValueForCastFunctionException ex) { @@ -237,7 +240,8 @@ public static TYPE requireType(Class clazz, IItem ite null, String.format("Expected non-null type '%s', but the node was null.", clazz.getName())); - } else if (!clazz.isInstance(item)) { + } + if (!clazz.isInstance(item)) { throw new InvalidTypeMetapathException( item, String.format("Expected type '%s', but the node was type '%s'.", diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeiling.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeiling.java index 407634a19..99626871e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeiling.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeiling.java @@ -20,8 +20,8 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * Implements the XPath 3.1 - * fn:round + * Implements the XPath 3.1 fn:ceiling * function. */ public final class FnCeiling { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java index 45bd024b3..7c871e279 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java @@ -15,13 +15,19 @@ import gov.nist.secauto.metaschema.core.metapath.item.IItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyUriItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBase64BinaryItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateTimeItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDecimalItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDurationItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IUntypedAtomicItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -37,7 +43,16 @@ public final class FnMinMax { private static final String NAME_MIN = "min"; private static final String NAME_MAX = "max"; - + @NonNull + private static final Set> PRIMITIVE_ITEM_TYPES = ObjectUtils.notNull(Set.of( + IStringItem.class, + IBooleanItem.class, + IDecimalItem.class, + IDurationItem.class, + IDateTimeItem.class, + IDateItem.class, + IBase64BinaryItem.class, + IAnyUriItem.class)); @NonNull static final IFunction SIGNATURE_MIN = IFunction.builder() .name(NAME_MIN) @@ -154,7 +169,7 @@ private static Stream normalize( .collect(Collectors.toList())); Map, Integer> counts = FunctionUtils.countTypes( - IAnyAtomicItem.PRIMITIVE_ITEM_TYPES, + PRIMITIVE_ITEM_TYPES, resultingItems); Stream stream = null; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAnyAtomicItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAnyAtomicItem.java index 334e0c92c..c12c9d4d2 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAnyAtomicItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAnyAtomicItem.java @@ -5,18 +5,19 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; -import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import edu.umd.cs.findbugs.annotations.NonNull; /** - * Provides a common implementation for all atomic types. + * Provides a common implementation for all atomic types that have an underlying + * value. * * @param * the Java type associated with the atomic type. */ -public abstract class AbstractAnyAtomicItem implements IAnyAtomicItem { +public abstract class AbstractAnyAtomicItem + extends AbstractAtomicItemBase { @NonNull private final TYPE value; @@ -36,17 +37,4 @@ public TYPE getValue() { return value; } - @Override - @NonNull - public abstract IDataTypeAdapter getJavaTypeAdapter(); - - @Override - public String asString() { - return getJavaTypeAdapter().asString(getValue()); - } - - @Override - public String toString() { - return asString(); - } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAtomicItemBase.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAtomicItemBase.java new file mode 100644 index 000000000..c3c3c6a92 --- /dev/null +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractAtomicItemBase.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: none + * SPDX-License-Identifier: CC0-1.0 + */ + +package gov.nist.secauto.metaschema.core.metapath.item.atomic; + +import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter; + +import edu.umd.cs.findbugs.annotations.NonNull; + +/** + * Provides base functionality for atomic item implementations. + * + * @param + * the Java type of the underlying data value + */ +public abstract class AbstractAtomicItemBase implements IAnyAtomicItem { + + @Override + @NonNull + public abstract IDataTypeAdapter getJavaTypeAdapter(); + + @Override + public String asString() { + return getJavaTypeAdapter().asString(getValue()); + } + + @Override + public String toString() { + return asString(); + } +} diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java index 13f20a671..78bccead3 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java @@ -7,26 +7,17 @@ import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter; import gov.nist.secauto.metaschema.core.metapath.IPrintable; +import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; import gov.nist.secauto.metaschema.core.metapath.item.IItemVisitor; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; -import gov.nist.secauto.metaschema.core.util.ObjectUtils; - -import java.util.Set; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * The interface shares by all atomic items. + */ public interface IAnyAtomicItem extends IAtomicValuedItem, IPrintable { - @NonNull - Set> PRIMITIVE_ITEM_TYPES = ObjectUtils.notNull(Set.of( - IStringItem.class, - IBooleanItem.class, - IDecimalItem.class, - IDurationItem.class, - IDateTimeItem.class, - IDateItem.class, - IBase64BinaryItem.class, - IAnyUriItem.class)); @Override @NonNull @@ -90,7 +81,9 @@ default IStringItem asStringItem() { * * @param item * the item to cast - * @return the result from casting + * @return an atomic item of this type + * @throws InvalidValueForCastFunctionException + * if the provided item type cannot be cast to this item type */ @NonNull IAnyAtomicItem castAsType(@NonNull IAnyAtomicItem item); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java index f9359fede..7208046ba 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java @@ -6,13 +6,18 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.AnyUriItemImpl; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.net.URI; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a URI data value. + */ public interface IAnyUriItem extends IAnyAtomicItem { /** * Construct a new URI item using the provided string {@code value}. @@ -20,12 +25,21 @@ public interface IAnyUriItem extends IAnyAtomicItem { * @param value * a string representing a URI * @return the new item - * @throws IllegalArgumentException + * @throws InvalidTypeMetapathException * if the given string violates RFC2396 */ @NonNull static IAnyUriItem valueOf(@NonNull String value) { - return valueOf(ObjectUtils.notNull(URI.create(value))); + try { + return valueOf(MetaschemaDataTypeProvider.URI.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid URI. %s", + value, + ex.getLocalizedMessage()), + ex); + } } /** @@ -59,7 +73,19 @@ static IAnyUriItem valueOf(@NonNull URI value) { */ @NonNull static IAnyUriItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.URI.cast(item); + try { + return item instanceof IAnyUriItem + ? (IAnyUriItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } + } + + @Override + default IAnyUriItem castAsType(IAnyAtomicItem item) { + return cast(item); } /** @@ -102,11 +128,6 @@ default IAnyUriItem resolve(@NonNull IAnyUriItem other) { return valueOf(ObjectUtils.notNull(asUri().resolve(other.asUri()))); } - @Override - default IAnyUriItem castAsType(IAnyAtomicItem item) { - return cast(item); - } - @Override default int compareTo(IAnyAtomicItem item) { return compareTo(cast(item)); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java index a86039042..ad6603d5e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java @@ -6,7 +6,9 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.Base64BinaryItemImpl; import java.nio.ByteBuffer; @@ -24,10 +26,21 @@ public interface IBase64BinaryItem extends IAnyAtomicItem { * @param value * a string representing base64 encoded data * @return the new item + * @throws InvalidTypeMetapathException + * if the provided string is not a valid Base64 character sequence */ @NonNull static IBase64BinaryItem valueOf(@NonNull String value) { - return cast(IStringItem.valueOf(value)); + try { + return valueOf(MetaschemaDataTypeProvider.BASE64.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value starting with '%s' is not a valid Base64 character sequence. %s", + value.substring(0, Math.min(value.length(), 200)), + ex.getLocalizedMessage()), + ex); + } } /** @@ -55,7 +68,14 @@ static IBase64BinaryItem valueOf(@NonNull ByteBuffer value) { */ @NonNull static IBase64BinaryItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.BASE64.cast(item); + try { + return item instanceof IBase64BinaryItem + ? (IBase64BinaryItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java index 79ad9ee28..9086e2056 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java @@ -6,7 +6,9 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.BooleanItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; @@ -34,6 +36,8 @@ public interface IBooleanItem extends IAnyAtomicItem { * @param value * a string representing a boolean value * @return the new item + * @throws InvalidTypeMetapathException + * if the provided value is not a valid boolean value */ @NonNull static IBooleanItem valueOf(@NonNull String value) { @@ -42,10 +46,13 @@ static IBooleanItem valueOf(@NonNull String value) { retval = TRUE; } else { try { - Boolean bool = MetaschemaDataTypeProvider.BOOLEAN.parse(value); - retval = valueOf(bool); + retval = valueOf(MetaschemaDataTypeProvider.BOOLEAN.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid boolean value. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -76,7 +83,29 @@ static IBooleanItem valueOf(boolean value) { */ @NonNull static IBooleanItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.BOOLEAN.cast(item); + IBooleanItem retval; + if (item instanceof INumericItem) { + retval = valueOf(((INumericItem) item).toEffectiveBoolean()); + } else { + try { + retval = valueOf(INumericItem.cast(item).toEffectiveBoolean()); + } catch (InvalidValueForCastFunctionException ex) { + try { + retval = valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex2) { + // asString can throw IllegalStateException exception + InvalidValueForCastFunctionException thrown = new InvalidValueForCastFunctionException(ex2); + thrown.addSuppressed(ex); + throw thrown; + } + } + } + return retval; + } + + @Override + default IBooleanItem castAsType(IAnyAtomicItem item) { + return cast(item); } /** @@ -86,11 +115,6 @@ static IBooleanItem cast(@NonNull IAnyAtomicItem item) { */ boolean toBoolean(); - @Override - default IBooleanItem castAsType(IAnyAtomicItem item) { - return cast(item); - } - /** * Get the boolean negation of this value. * @@ -103,7 +127,7 @@ default IBooleanItem negate() { @Override default int compareTo(IAnyAtomicItem item) { - return compareTo(cast(item)); + return compareTo(castAsType(item)); } /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java index 4223748a3..9984156fa 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java @@ -7,7 +7,10 @@ import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.object.Date; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DateWithTimeZoneItemImpl; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DateWithoutTimeZoneItemImpl; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.time.ZonedDateTime; @@ -15,6 +18,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a date data value. + */ public interface IDateItem extends ITemporalItem { /** @@ -29,7 +35,12 @@ static IDateItem valueOf(@NonNull String value) { try { return valueOf(MetaschemaDataTypeProvider.DATE.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), ex); + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid date. %s", + value, + ex.getLocalizedMessage()), + ex); } } @@ -71,13 +82,28 @@ static IDateItem valueOf(@NonNull ZonedDateTime value) { */ @NonNull static IDateItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.DATE.cast(item); + IDateItem retval; + if (item instanceof IDateItem) { + retval = (IDateItem) item; + } else if (item instanceof IDateTimeItem) { + ZonedDateTime value = ((IDateTimeItem) item).asZonedDateTime(); + retval = valueOf(value); + } else if (item instanceof IStringItem || item instanceof IUntypedAtomicItem) { + try { + retval = valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } + } else { + throw new InvalidValueForCastFunctionException( + String.format("unsupported item type '%s'", item.getClass().getName())); + } + return retval; } @Override - default IDateItem castAsType(IAnyAtomicItem item) { - return cast(item); - } + IDateItem castAsType(IAnyAtomicItem item); @Override default int compareTo(IAnyAtomicItem item) { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java index 40088877f..5daa1b735 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java @@ -7,12 +7,18 @@ import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.object.DateTime; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DateTimeWithTimeZoneItemImpl; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DateTimeWithoutTimeZoneItemImpl; import java.time.ZonedDateTime; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a date/time data value. + */ public interface IDateTimeItem extends ITemporalItem { /** * Construct a new date/time item using the provided string {@code value}. @@ -26,7 +32,11 @@ static IDateTimeItem valueOf(@NonNull String value) { try { return valueOf(MetaschemaDataTypeProvider.DATE_TIME.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid date/time. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -67,7 +77,23 @@ static IDateTimeItem valueOf(@NonNull ZonedDateTime value) { */ @NonNull static IDateTimeItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.DATE_TIME.cast(item); + IDateTimeItem retval; + if (item instanceof IDateTimeItem) { + retval = (IDateTimeItem) item; + } else { + String itemString = item.asString(); + try { + retval = valueOf(itemString); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException( + String.format("The value '%s' is not compatible with the type '%s'", + item.getValue(), + item.getClass().getName()), + ex); + } + } + return retval; } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java index 2d47ba484..cee41f074 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java @@ -6,12 +6,18 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DayTimeDurationItemImpl; import java.time.Duration; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a duration data value in days, hours, and + * seconds. + */ public interface IDayTimeDurationItem extends IDurationItem { /** * Construct a new day time duration item using the provided string @@ -20,13 +26,20 @@ public interface IDayTimeDurationItem extends IDurationItem { * @param value * a string representing a day time duration * @return the new item + * @throws InvalidTypeMetapathException + * if the provided string value is not a day/time duration value + * according to ISO 8601 */ @NonNull static IDayTimeDurationItem valueOf(@NonNull String value) { try { return valueOf(MetaschemaDataTypeProvider.DAY_TIME_DURATION.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid day/time duration. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -55,7 +68,14 @@ static IDayTimeDurationItem valueOf(@NonNull Duration value) { */ @NonNull static IDayTimeDurationItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.DAY_TIME_DURATION.cast(item); + try { + return item instanceof IDayTimeDurationItem + ? (IDayTimeDurationItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java index b6e4e9925..24eaf8a55 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java @@ -6,19 +6,25 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DecimalItemImpl; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.math.BigDecimal; import java.math.RoundingMode; import edu.umd.cs.findbugs.annotations.NonNull; -import edu.umd.cs.findbugs.annotations.Nullable; +/** + * A Metapath atomic item containing a decimal data value. + */ public interface IDecimalItem extends INumericItem { - @SuppressWarnings("null") + /** + * The decimal item with the value "0". + */ @NonNull - IDecimalItem ZERO = valueOf(BigDecimal.ZERO); + IDecimalItem ZERO = valueOf(ObjectUtils.notNull(BigDecimal.ZERO)); /** * Construct a new decimal item using the provided string {@code value}. @@ -26,13 +32,19 @@ public interface IDecimalItem extends INumericItem { * @param value * a string representing a decimal value * @return the new item + * @throws InvalidTypeMetapathException + * if the given string is not a decimal value */ @NonNull static IDecimalItem valueOf(@NonNull String value) { try { return valueOf(MetaschemaDataTypeProvider.DECIMAL.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid decimal. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -61,6 +73,18 @@ static IDecimalItem valueOf(double value) { return valueOf(ObjectUtils.notNull(Double.toString(value))); } + /** + * Construct a new decimal item using the provided {@code value}. + * + * @param value + * a double value + * @return the new item + */ + @NonNull + static IDecimalItem valueOf(boolean value) { + return valueOf(DecimalItemImpl.toBigDecimal(value)); + } + /** * Construct a new decimal item using the provided {@code value}. * @@ -84,13 +108,28 @@ static IDecimalItem valueOf(@NonNull BigDecimal value) { * if the provided {@code item} cannot be cast to this type */ @NonNull - static IDecimalItem cast(@Nullable IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.DECIMAL.cast(item); + static IDecimalItem cast(@NonNull IAnyAtomicItem item) { + IDecimalItem retval; + if (item instanceof IDecimalItem) { + retval = (IDecimalItem) item; + } else if (item instanceof INumericItem) { + retval = valueOf(((INumericItem) item).asDecimal()); + } else if (item instanceof IBooleanItem) { + retval = valueOf(((IBooleanItem) item).toBoolean()); + } else { + try { + retval = valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } + } + return retval; } @Override default IDecimalItem castAsType(IAnyAtomicItem item) { - return valueOf(cast(item).asDecimal()); + return cast(item); } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java index ce9817e24..7d318a8d3 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java @@ -11,6 +11,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item representing a duration data value. + */ public interface IDurationItem extends IAnyAtomicItem { /** * Cast the provided type to this item type. @@ -28,11 +31,19 @@ static IDurationItem cast(@NonNull IAnyAtomicItem item) { if (item instanceof IDurationItem) { retval = (IDurationItem) item; } else { + String value; + try { + value = item.asString(); + } catch (IllegalStateException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } + try { - retval = IDayTimeDurationItem.valueOf(item.asString()); + retval = IDayTimeDurationItem.valueOf(value); } catch (IllegalStateException ex) { try { - retval = IYearMonthDurationItem.valueOf(item.asString()); + retval = IYearMonthDurationItem.valueOf(value); } catch (IllegalStateException ex2) { InvalidValueForCastFunctionException newEx = new InvalidValueForCastFunctionException(ex2); newEx.addSuppressed(ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java index ddfe5d54f..400a0b339 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java @@ -6,10 +6,15 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.EmailAddressItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing an email address data value. + */ public interface IEmailAddressItem extends IStringItem { /** * Construct a new email address item using the provided string {@code value}. @@ -17,13 +22,19 @@ public interface IEmailAddressItem extends IStringItem { * @param value * a string representing an email address value * @return the new item + * @throws InvalidTypeMetapathException + * if the given string is not an email address value */ @NonNull static IEmailAddressItem valueOf(@NonNull String value) { try { return new EmailAddressItemImpl(MetaschemaDataTypeProvider.EMAIL_ADDRESS.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid email address. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -40,7 +51,14 @@ static IEmailAddressItem valueOf(@NonNull String value) { */ @NonNull static IEmailAddressItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.EMAIL_ADDRESS.cast(item); + try { + return item instanceof IEmailAddressItem + ? (IEmailAddressItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java index 61fb7086a..6257b6400 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java @@ -6,10 +6,15 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.HostnameItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a hostname data value. + */ public interface IHostnameItem extends IStringItem { /** * Construct a new host name item using the provided string {@code value}. @@ -23,7 +28,11 @@ static IHostnameItem valueOf(@NonNull String value) { try { return new HostnameItemImpl(MetaschemaDataTypeProvider.HOSTNAME.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid hostname. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -40,7 +49,14 @@ static IHostnameItem valueOf(@NonNull String value) { */ @NonNull static IHostnameItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.HOSTNAME.cast(item); + try { + return item instanceof IHostnameItem + ? (IHostnameItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java index 687f4be5e..852c169d1 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java @@ -5,9 +5,14 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; +import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; + import edu.umd.cs.findbugs.annotations.NonNull; import inet.ipaddr.IPAddress; +/** + * A Metapath atomic item representing an IP address data value. + */ public interface IIPAddressItem extends IUntypedAtomicItem { /** * Get the "wrapped" IP address value. @@ -28,4 +33,32 @@ public interface IIPAddressItem extends IUntypedAtomicItem { default int compareTo(IIPAddressItem item) { return asIpAddress().compareTo(item.asIpAddress()); } + + /** + * Cast the provided type to this item type. + * + * @param item + * the item to cast + * @return the original item if it is already this type, otherwise a new item + * cast to this type + * @throws InvalidValueForCastFunctionException + * if the provided {@code item} cannot be cast to this type + */ + @NonNull + static IIPAddressItem cast(@NonNull IAnyAtomicItem item) { + if (!(item instanceof IIPAddressItem)) { + String value = null; + try { + value = item.asString(); + } catch (IllegalStateException ex) { + // do nothing + } + + throw new InvalidValueForCastFunctionException( + String.format("The value '%s' of type '%s' is not an internet protocol address.", + value, + item.getJavaTypeAdapter().getPreferredName())); + } + return (IIPv4AddressItem) item; + } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java index e24c1c9d3..33e0d5668 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java @@ -6,13 +6,39 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.IPv4AddressItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; import inet.ipaddr.ipv4.IPv4Address; +/** + * A Metapath atomic item containing an IPv4 address data value. + */ public interface IIPv4AddressItem extends IIPAddressItem { + /** + * Construct a new IPv4 item using the provided {@code value}. + * + * @param value + * an IPv4 value + * @return the new item + */ + @NonNull + static IIPv4AddressItem valueOf(@NonNull String value) { + try { + return valueOf(MetaschemaDataTypeProvider.IP_V4_ADDRESS.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid IPv4 address. %s", + value, + ex.getLocalizedMessage()), + ex); + } + } + /** * Construct a new IPv4 item using the provided {@code value}. * @@ -37,7 +63,14 @@ static IIPv4AddressItem valueOf(@NonNull IPv4Address value) { */ @NonNull static IIPv4AddressItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.IP_V4_ADDRESS.cast(item); + try { + return item instanceof IIPv4AddressItem + ? (IIPv4AddressItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java index 23edb002c..c3c9b2a46 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java @@ -6,13 +6,39 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.IPv6AddressItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; import inet.ipaddr.ipv6.IPv6Address; +/** + * A Metapath atomic item containing an IPv4 address data value. + */ public interface IIPv6AddressItem extends IIPAddressItem { + /** + * Construct a new IPv6 item using the provided {@code value}. + * + * @param value + * an IPv6 value + * @return the new item + */ + @NonNull + static IIPv6AddressItem valueOf(@NonNull String value) { + try { + return valueOf(MetaschemaDataTypeProvider.IP_V6_ADDRESS.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid IPv6 address. %s", + value, + ex.getLocalizedMessage()), + ex); + } + } + /** * Construct a new IPv6 item using the provided {@code value}. * @@ -37,7 +63,14 @@ static IIPv6AddressItem valueOf(@NonNull IPv6Address value) { */ @NonNull static IIPv6AddressItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.IP_V6_ADDRESS.cast(item); + try { + return item instanceof IIPv6AddressItem + ? (IIPv6AddressItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java index db6b14002..f40ba46b8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java @@ -5,25 +5,34 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; -import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.IntegerItemImpl; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.math.BigInteger; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing an integer data value. + */ public interface IIntegerItem extends IDecimalItem { - - @SuppressWarnings("null") + /** + * The integer value "1". + */ @NonNull - IIntegerItem ONE = valueOf(BigInteger.ONE); - @SuppressWarnings("null") + IIntegerItem ONE = valueOf(ObjectUtils.notNull(BigInteger.ONE)); + /** + * The integer value "0". + */ @NonNull - IIntegerItem ZERO = valueOf(BigInteger.ZERO); - @SuppressWarnings("null") + IIntegerItem ZERO = valueOf(ObjectUtils.notNull(BigInteger.ZERO)); + /** + * The integer value "-1". + */ @NonNull - IIntegerItem NEGATIVE_ONE = valueOf(BigInteger.ONE.negate()); + IIntegerItem NEGATIVE_ONE = valueOf(ObjectUtils.notNull(BigInteger.ONE.negate())); /** * Create an item from an existing integer value. @@ -75,6 +84,18 @@ static IIntegerItem valueOf(long value) { return valueOf(bigInteger); } + /** + * Construct a new integer item using the provided {@code value}. + * + * @param value + * a long value + * @return the new item + */ + @NonNull + static IIntegerItem valueOf(boolean value) { + return valueOf(ObjectUtils.notNull(value ? BigInteger.ONE : BigInteger.ZERO)); + } + /** * Construct a new integer item using the provided {@code value}. * @@ -109,7 +130,27 @@ static IIntegerItem valueOf(@NonNull BigInteger value) { */ @NonNull static IIntegerItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.INTEGER.cast(item); + IIntegerItem retval; + if (item instanceof IIntegerItem) { + retval = (IIntegerItem) item; + } else if (item instanceof INumericItem) { + retval = valueOf(((INumericItem) item).asInteger()); + } else if (item instanceof IBooleanItem) { + retval = valueOf(((IBooleanItem) item).toBoolean()); + } else { + try { + retval = valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } + } + return retval; + } + + @Override + default IIntegerItem castAsType(IAnyAtomicItem item) { + return cast(item); } @Override @@ -125,11 +166,6 @@ default IIntegerItem floor() { return this; } - @Override - default IIntegerItem castAsType(IAnyAtomicItem item) { - return valueOf(cast(item).asInteger()); - } - @Override default int compareTo(IAnyAtomicItem item) { return compareTo(cast(item)); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java index 22f450021..7d657cf39 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java @@ -9,11 +9,30 @@ import gov.nist.secauto.metaschema.core.datatype.markup.MarkupDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.MarkupLineItemImpl; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.MarkupMultiLineItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item representing a Markup data value. + */ public interface IMarkupItem extends IUntypedAtomicItem { + /** + * Construct a new item using the provided {@code value}. + * + * @param value + * a line of markup + * @return the new item + */ + @NonNull + static IMarkupItem valueOf(@NonNull String value) { + // TODO: figure out what error is returned + return valueOf(MarkupDataTypeProvider.MARKUP_LINE.parse(value)); + } + /** * Construct a new item using the provided {@code value}. * @@ -50,7 +69,14 @@ static IMarkupItem valueOf(@NonNull MarkupMultiline value) { */ @NonNull static IMarkupItem cast(@NonNull IAnyAtomicItem item) { - return MarkupDataTypeProvider.MARKUP_MULTILINE.cast(item); + try { + return item instanceof IMarkupItem + ? (IMarkupItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java index e26b346f8..05a5a9470 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java @@ -6,10 +6,15 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.NcNameItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a non-colonized name data value. + */ @Deprecated(forRemoval = true, since = "0.7.0") public interface INcNameItem extends IStringItem { /** @@ -25,7 +30,11 @@ static INcNameItem valueOf(@NonNull String value) { try { return new NcNameItemImpl(MetaschemaDataTypeProvider.NCNAME.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid non-colonized name. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -42,7 +51,14 @@ static INcNameItem valueOf(@NonNull String value) { */ @NonNull static INcNameItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.NCNAME.cast(item); + try { + return item instanceof INcNameItem + ? (INcNameItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java index b346796e9..b3dc83a59 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java @@ -8,18 +8,27 @@ import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.NonNegativeIntegerItemImpl; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.math.BigInteger; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a non-negative integer data value. + */ public interface INonNegativeIntegerItem extends IIntegerItem { - @SuppressWarnings("null") + /** + * The integer value "1". + */ @NonNull - INonNegativeIntegerItem ONE = valueOf(BigInteger.ONE); - @SuppressWarnings("null") + INonNegativeIntegerItem ONE = valueOf(ObjectUtils.notNull(BigInteger.ONE)); + /** + * The integer value "0". + */ @NonNull - INonNegativeIntegerItem ZERO = valueOf(BigInteger.ZERO); + INonNegativeIntegerItem ZERO = valueOf(ObjectUtils.notNull(BigInteger.ZERO)); /** * Create an item from an existing integer value. @@ -33,10 +42,13 @@ public interface INonNegativeIntegerItem extends IIntegerItem { @NonNull static INonNegativeIntegerItem valueOf(@NonNull String value) { try { - return valueOf(new BigInteger(value)); - } catch (NumberFormatException ex) { - throw new InvalidTypeMetapathException(null, - ex.getMessage(), + return new NonNegativeIntegerItemImpl(MetaschemaDataTypeProvider.NON_NEGATIVE_INTEGER.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid non-negative integer. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -51,7 +63,7 @@ static INonNegativeIntegerItem valueOf(@NonNull String value) { * if the provided value is not a non-negative integer */ @NonNull - static INonNegativeIntegerItem valueOf(@NonNull IIntegerItem value) { + static INonNegativeIntegerItem valueOf(@NonNull INumericItem value) { return valueOf(value.asInteger()); } @@ -101,11 +113,19 @@ static INonNegativeIntegerItem valueOf(@NonNull BigInteger value) { */ @NonNull static INonNegativeIntegerItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.NON_NEGATIVE_INTEGER.cast(item); + try { + return item instanceof INonNegativeIntegerItem + ? (INonNegativeIntegerItem) item + : item instanceof INumericItem + ? valueOf((INumericItem) item) + : valueOf(item.asString()); + } catch (InvalidTypeMetapathException ex) { + throw new InvalidValueForCastFunctionException(ex); + } } @Override default INonNegativeIntegerItem castAsType(IAnyAtomicItem item) { - return valueOf(cast(item).asInteger()); + return cast(item); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java index 6bab669ca..9762510e3 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java @@ -5,7 +5,7 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; -import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.ArithmeticFunctionException; import gov.nist.secauto.metaschema.core.metapath.function.FunctionUtils; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; @@ -18,6 +18,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a numeric data value. + */ public interface INumericItem extends IAnyAtomicItem { /** @@ -32,7 +35,14 @@ public interface INumericItem extends IAnyAtomicItem { */ @NonNull static INumericItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.DECIMAL.cast(item); + try { + return item instanceof INumericItem + ? (INumericItem) item + : IDecimalItem.valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java index 7eff6798c..009b050db 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java @@ -5,15 +5,21 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; -import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.PositiveIntegerItemImpl; import java.math.BigInteger; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a positive integer data value. + */ public interface IPositiveIntegerItem extends INonNegativeIntegerItem { + /** + * The integer value "1". + */ @SuppressWarnings("null") @NonNull IPositiveIntegerItem ONE = valueOf(BigInteger.ONE); @@ -31,9 +37,12 @@ public interface IPositiveIntegerItem extends INonNegativeIntegerItem { static IPositiveIntegerItem valueOf(@NonNull String value) { try { return valueOf(new BigInteger(value)); - } catch (NumberFormatException ex) { - throw new InvalidTypeMetapathException(null, - ex.getMessage(), + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid positive integer. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -48,7 +57,7 @@ static IPositiveIntegerItem valueOf(@NonNull String value) { * if the provided value is not a positive integer */ @NonNull - static IPositiveIntegerItem valueOf(@NonNull IIntegerItem value) { + static IPositiveIntegerItem valueOf(@NonNull INumericItem value) { return valueOf(value.asInteger()); } @@ -98,11 +107,20 @@ static IPositiveIntegerItem valueOf(@NonNull BigInteger value) { */ @NonNull static IPositiveIntegerItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.POSITIVE_INTEGER.cast(item); + try { + return item instanceof IPositiveIntegerItem + ? (IPositiveIntegerItem) item + : item instanceof INumericItem + ? valueOf((INumericItem) item) + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override default IPositiveIntegerItem castAsType(IAnyAtomicItem item) { - return valueOf(cast(item).asInteger()); + return cast(item); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java index b1d7de5c5..e4e31a2bd 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java @@ -5,10 +5,16 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; +import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.StringItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a text data value. + */ public interface IStringItem extends IAnyAtomicItem { /** * Construct a new item using the provided string {@code value}. @@ -19,7 +25,16 @@ public interface IStringItem extends IAnyAtomicItem { */ @NonNull static IStringItem valueOf(@NonNull String value) { - return new StringItemImpl(value); + try { + return new StringItemImpl(MetaschemaDataTypeProvider.STRING.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid IPv4 address. %s", + value, + ex.getLocalizedMessage()), + ex); + } } /** @@ -35,9 +50,12 @@ static IStringItem valueOf(@NonNull String value) { @NonNull static IStringItem cast(@NonNull IAnyAtomicItem item) { try { - return item.asStringItem(); + return item instanceof IStringItem + ? (IStringItem) item + : valueOf(item.asString()); } catch (IllegalStateException ex) { - throw new InvalidValueForCastFunctionException(ex.getLocalizedMessage(), ex); + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java index f95bd0ebc..fb92e5d79 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java @@ -9,6 +9,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a temporal data value. + */ public interface ITemporalItem extends IAnyAtomicItem { /** * Determine if the temporal item has a timezone. diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java index 9de2438e3..56ab75625 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java @@ -6,10 +6,15 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.TokenItemImpl; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a text token data value. + */ public interface ITokenItem extends IStringItem { /** * Construct a new item using the provided string {@code value}. @@ -17,13 +22,19 @@ public interface ITokenItem extends IStringItem { * @param value * a string representing a token value * @return the new item + * @throws InvalidTypeMetapathException + * if the provided value is not a token */ @NonNull static ITokenItem valueOf(@NonNull String value) { try { return new TokenItemImpl(MetaschemaDataTypeProvider.TOKEN.parse(value)); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid token. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -40,7 +51,13 @@ static ITokenItem valueOf(@NonNull String value) { */ @NonNull static ITokenItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.TOKEN.cast(item); + try { + return item instanceof ITokenItem + ? (ITokenItem) item + : valueOf(item.asString()); + } catch (InvalidTypeMetapathException ex) { + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java index fc73fec57..555b2c7de 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java @@ -5,6 +5,9 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; +/** + * A Metapath atomic item containing an untyped atomic data value. + */ public interface IUntypedAtomicItem extends IAnyAtomicItem { // this interface has no additional methods } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java index 6a40b728a..337b36a2d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java @@ -6,13 +6,41 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.UriReferenceItemImpl; import java.net.URI; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a URI reference data value. + */ public interface IUriReferenceItem extends IAnyUriItem { + /** + * Construct a new URI item using the provided string {@code value}. + * + * @param value + * a string representing a URI + * @return the new item + * @throws InvalidTypeMetapathException + * if the given string violates RFC2396 + */ + @NonNull + static IUriReferenceItem valueOf(@NonNull String value) { + try { + return valueOf(MetaschemaDataTypeProvider.URI_REFERENCE.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid URI reference. %s", + value, + ex.getLocalizedMessage()), + ex); + } + } + /** * Construct a new item using the provided URI {@code value}. * @@ -37,7 +65,16 @@ static IUriReferenceItem valueOf(@NonNull URI value) { */ @NonNull static IUriReferenceItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.URI_REFERENCE.cast(item); + try { + return item instanceof IUriReferenceItem + ? (IUriReferenceItem) item + : item instanceof IAnyUriItem + ? valueOf(((IAnyUriItem) item).asUri()) + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java index b942c823c..b3b11a035 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java @@ -6,13 +6,40 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.UuidItemImpl; import java.util.UUID; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a UUID data value. + */ public interface IUuidItem extends IStringItem { + /** + * Construct a new URI item using the provided string {@code value}. + * + * @param value + * a string representing a URI + * @return the new item + * @throws InvalidTypeMetapathException + * if the given string violates RFC4122 + */ + @NonNull + static IUuidItem valueOf(@NonNull String value) { + try { + return valueOf(MetaschemaDataTypeProvider.UUID.parse(value)); + } catch (IllegalArgumentException ex) { + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid UUID. %s", + value, + ex.getLocalizedMessage()), + ex); + } + } /** * Construct a new item using the provided {@code value}. @@ -49,7 +76,14 @@ static IUuidItem random() { */ @NonNull static IUuidItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.UUID.cast(item); + try { + return item instanceof IUuidItem + ? (IUuidItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java index 20bd2066f..db2fcea69 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java @@ -6,13 +6,18 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.YearMonthDurationItemImpl; import gov.nist.secauto.metaschema.core.util.ObjectUtils; import java.time.Period; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A Metapath atomic item containing a duration data value in years and months. + */ public interface IYearMonthDurationItem extends IDurationItem { /** * Construct a new year month day duration item using the provided string @@ -21,6 +26,9 @@ public interface IYearMonthDurationItem extends IDurationItem { * @param value * a string representing a year month day duration * @return the new item + * @throws InvalidTypeMetapathException + * if the provided string value is not a day/time duration value + * according to ISO 8601 */ @NonNull static IYearMonthDurationItem valueOf(@NonNull String value) { @@ -28,7 +36,11 @@ static IYearMonthDurationItem valueOf(@NonNull String value) { Period period = ObjectUtils.notNull(MetaschemaDataTypeProvider.YEAR_MONTH_DURATION.parse(value).withDays(0)); return valueOf(period); } catch (IllegalArgumentException ex) { - throw new InvalidValueForCastFunctionException(String.format("Unable to parse string value '%s'", value), + throw new InvalidTypeMetapathException( + null, + String.format("The value '%s' is not a valid year/month duration. %s", + value, + ex.getLocalizedMessage()), ex); } } @@ -55,10 +67,9 @@ static IYearMonthDurationItem valueOf(@NonNull Period value) { * the number of months in the period * @return the new item */ - @SuppressWarnings("null") @NonNull static IYearMonthDurationItem valueOf(int years, int months) { - return valueOf(Period.of(years, months, 0)); + return valueOf(ObjectUtils.notNull(Period.of(years, months, 0))); } /** @@ -73,7 +84,14 @@ static IYearMonthDurationItem valueOf(int years, int months) { */ @NonNull static IYearMonthDurationItem cast(@NonNull IAnyAtomicItem item) { - return MetaschemaDataTypeProvider.YEAR_MONTH_DURATION.cast(item); + try { + return item instanceof IYearMonthDurationItem + ? (IYearMonthDurationItem) item + : valueOf(item.asString()); + } catch (IllegalStateException | InvalidTypeMetapathException ex) { + // asString can throw IllegalStateException exception + throw new InvalidValueForCastFunctionException(ex); + } } /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDateItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDateItem.java similarity index 56% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDateItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDateItem.java index 35d2a708c..839c1b9c7 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDateItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDateItem.java @@ -3,10 +3,20 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; + +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateItem; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * An abstract implementation of a Metapath atomic item containing a date data + * value. + * + * @param + * the Java type of the wrapped value + */ public abstract class AbstractDateItem extends AbstractTemporalItem implements IDateItem { @@ -25,6 +35,11 @@ public boolean hasTimezone() { return true; } + @Override + public IDateItem castAsType(IAnyAtomicItem item) { + return IDateItem.cast(item); + } + @Override public int hashCode() { return asZonedDateTime().hashCode(); @@ -34,6 +49,6 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IDateItem && compareTo((IDateItem) obj) == 0); + || obj instanceof IDateItem && compareTo((IDateItem) obj) == 0; } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDateTimeItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDateTimeItem.java similarity index 55% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDateTimeItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDateTimeItem.java index 0e363d8ab..ea66ba041 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDateTimeItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDateTimeItem.java @@ -3,10 +3,20 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; + +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateTimeItem; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * An abstract implementation of a Metapath atomic item containing a date/time + * data value. + * + * @param + * the Java type of the wrapped value + */ public abstract class AbstractDateTimeItem extends AbstractTemporalItem implements IDateTimeItem { @@ -25,6 +35,11 @@ public boolean hasTimezone() { return true; } + @Override + public IDateTimeItem castAsType(IAnyAtomicItem item) { + return IDateTimeItem.cast(item); + } + @Override public int hashCode() { return asZonedDateTime().hashCode(); @@ -34,6 +49,6 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IDateTimeItem && compareTo((IDateTimeItem) obj) == 0); + || obj instanceof IDateTimeItem && compareTo((IDateTimeItem) obj) == 0; } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDecimalItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDecimalItem.java similarity index 66% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDecimalItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDecimalItem.java index 78a5ab290..0d026d9f5 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractDecimalItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractDecimalItem.java @@ -3,12 +3,21 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDecimalItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * An abstract implementation of a Metapath atomic item containing a decimal + * data value. + * + * @param + * the Java type of the wrapped value + */ public abstract class AbstractDecimalItem extends AbstractAnyAtomicItem implements IDecimalItem { @@ -44,8 +53,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj || - (obj instanceof AbstractDecimalItem.MapKey - && getKey().asDecimal().equals(((AbstractDecimalItem.MapKey) obj).getKey().asDecimal())); + obj instanceof AbstractDecimalItem.MapKey + && getKey().asDecimal().equals(((AbstractDecimalItem.MapKey) obj).getKey().asDecimal()); } } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractIntegerItem.java similarity index 79% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractIntegerItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractIntegerItem.java index 051ea784f..a408137a4 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractIntegerItem.java @@ -3,7 +3,9 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; + +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIntegerItem; import java.math.BigDecimal; import java.math.BigInteger; @@ -11,6 +13,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * An abstract implementation of a Metapath atomic item containing an integer + * data value. + */ public abstract class AbstractIntegerItem extends AbstractDecimalItem implements IIntegerItem { @@ -55,6 +61,6 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IIntegerItem && compareTo((IIntegerItem) obj) == 0); + || obj instanceof IIntegerItem && compareTo((IIntegerItem) obj) == 0; } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractStringItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java similarity index 82% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractStringItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java index 343c829c2..486da4d03 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractStringItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java @@ -3,15 +3,20 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.metapath.impl.AbstractStringMapKey; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import java.util.regex.Pattern; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A common base class for all items derived from {@link IStringItem}. + */ public abstract class AbstractStringItem extends AbstractAnyAtomicItem implements IStringItem { @@ -49,7 +54,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IStringItem && compareTo((IStringItem) obj) == 0); + || obj instanceof IStringItem && compareTo((IStringItem) obj) == 0; } private final class MapKey diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractTemporalItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractTemporalItem.java similarity index 81% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractTemporalItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractTemporalItem.java index 893e10ce2..108d927be 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractTemporalItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractTemporalItem.java @@ -3,14 +3,16 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.ITemporalItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import edu.umd.cs.findbugs.annotations.NonNull; /** - * A base class for temporal items. + * A base class for all items derived from {@link ITemporalItem}. * * @param * the Java type of the wrapped value diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractUriItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractUriItem.java similarity index 73% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractUriItem.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractUriItem.java index d65829b7b..3f8c49d2c 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AbstractUriItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractUriItem.java @@ -3,15 +3,21 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.metapath.impl.AbstractStringMapKey; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IAnyUriItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import java.net.URI; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * An abstract implementation of a Metapath atomic item containing a URI data + * value. + */ public abstract class AbstractUriItem extends AbstractAnyAtomicItem implements IAnyUriItem { @@ -46,7 +52,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IAnyUriItem && compareTo((IAnyUriItem) obj) == 0); + || obj instanceof IAnyUriItem && compareTo((IAnyUriItem) obj) == 0; } private final class MapKey diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AnyUriItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AnyUriItemImpl.java similarity index 62% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AnyUriItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AnyUriItemImpl.java index aada02c99..7df2600cb 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/AnyUriItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AnyUriItemImpl.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.UriAdapter; @@ -12,9 +12,18 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class AnyUriItemImpl +/** + * An implementation of a Metapath atomic item containing a URI data value. + */ +public class AnyUriItemImpl extends AbstractUriItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public AnyUriItemImpl(@NonNull URI value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/Base64BinaryItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/Base64BinaryItemImpl.java similarity index 66% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/Base64BinaryItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/Base64BinaryItemImpl.java index e742a4340..4ec1450b6 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/Base64BinaryItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/Base64BinaryItemImpl.java @@ -3,20 +3,32 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.Base64Adapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBase64BinaryItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import java.nio.ByteBuffer; import edu.umd.cs.findbugs.annotations.NonNull; -class Base64BinaryItemImpl +/** + * An implementation of a Metapath atomic item containing a Base64 encoded data + * value. + */ +public class Base64BinaryItemImpl extends AbstractAnyAtomicItem implements IBase64BinaryItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public Base64BinaryItemImpl(@NonNull ByteBuffer value) { super(value); } @@ -45,7 +57,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IBase64BinaryItem && compareTo((IBase64BinaryItem) obj) == 0); + || obj instanceof IBase64BinaryItem && compareTo((IBase64BinaryItem) obj) == 0; } private final class MapKey implements IMapKey { @@ -62,8 +74,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj || - (obj instanceof MapKey - && getKey().equals(((MapKey) obj).getKey())); + obj instanceof MapKey + && getKey().equals(((MapKey) obj).getKey()); } } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/BooleanItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/BooleanItemImpl.java similarity index 66% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/BooleanItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/BooleanItemImpl.java index 2c74b9043..09522bc68 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/BooleanItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/BooleanItemImpl.java @@ -3,15 +3,23 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.IDataTypeAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAtomicItemBase; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IBooleanItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import edu.umd.cs.findbugs.annotations.NonNull; -class BooleanItemImpl implements IBooleanItem { +/** + * An implementation of a Metapath atomic item with a boolean value. + */ +public class BooleanItemImpl + extends AbstractAtomicItemBase + implements IBooleanItem { @NonNull private static final String TRUE_STRING = "true"; @NonNull @@ -23,8 +31,14 @@ class BooleanItemImpl implements IBooleanItem { private final boolean booleanValue; - BooleanItemImpl(boolean booleanValue) { - this.booleanValue = booleanValue; + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ + public BooleanItemImpl(boolean value) { + this.booleanValue = value; } @Override @@ -48,7 +62,7 @@ public IStringItem asStringItem() { } @Override - public IDataTypeAdapter getJavaTypeAdapter() { + public IDataTypeAdapter getJavaTypeAdapter() { return MetaschemaDataTypeProvider.BOOLEAN; } @@ -71,7 +85,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IBooleanItem && compareTo((IBooleanItem) obj) == 0); + || obj instanceof IBooleanItem && compareTo((IBooleanItem) obj) == 0; } private final class MapKey implements IMapKey { @@ -88,8 +102,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj || - (obj instanceof MapKey - && getKey().equals(((MapKey) obj).getKey())); + obj instanceof MapKey + && getKey().equals(((MapKey) obj).getKey()); } } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateTimeWithTimeZoneItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithTimeZoneItemImpl.java similarity index 65% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateTimeWithTimeZoneItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithTimeZoneItemImpl.java index 1dd0e4efa..af12a8eae 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateTimeWithTimeZoneItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithTimeZoneItemImpl.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.DateTimeWithTZAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; @@ -12,9 +12,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class DateTimeWithTimeZoneItemImpl +/** + * An implementation of a Metapath atomic item containing a date/time data value + * that has a required timezone. + */ +public class DateTimeWithTimeZoneItemImpl extends AbstractDateTimeItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public DateTimeWithTimeZoneItemImpl(@NonNull ZonedDateTime value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateTimeWithoutTimeZoneItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java similarity index 66% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateTimeWithoutTimeZoneItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java index 182a7bcdf..8a9241d68 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateTimeWithoutTimeZoneItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.DateTimeAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; @@ -13,9 +13,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class DateTimeWithoutTimeZoneItemImpl +/** + * An implementation of a Metapath atomic item containing a date/time data value + * that may not have an explicit timezone. + */ +public class DateTimeWithoutTimeZoneItemImpl extends AbstractDateTimeItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public DateTimeWithoutTimeZoneItemImpl(@NonNull DateTime value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateWithTimeZoneItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithTimeZoneItemImpl.java similarity index 65% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateWithTimeZoneItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithTimeZoneItemImpl.java index 810aa6066..59de345b8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateWithTimeZoneItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithTimeZoneItemImpl.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.DateWithTZAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; @@ -12,9 +12,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class DateWithTimeZoneItemImpl +/** + * An implementation of a Metapath atomic item containing a date data value that + * has a required timezone. + */ +public class DateWithTimeZoneItemImpl extends AbstractDateItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public DateWithTimeZoneItemImpl(@NonNull ZonedDateTime value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateWithoutTimeZoneItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java similarity index 65% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateWithoutTimeZoneItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java index 806cee2ce..fc2948fb5 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DateWithoutTimeZoneItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.DateAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; @@ -13,9 +13,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class DateWithoutTimeZoneItemImpl +/** + * An implementation of a Metapath atomic item containing a date data value that + * may not have an explicit timezone. + */ +public class DateWithoutTimeZoneItemImpl extends AbstractDateItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public DateWithoutTimeZoneItemImpl(@NonNull Date value) { super(value); } @@ -29,4 +39,5 @@ public ZonedDateTime asZonedDateTime() { public DateAdapter getJavaTypeAdapter() { return MetaschemaDataTypeProvider.DATE; } + } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DayTimeDurationItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DayTimeDurationItemImpl.java similarity index 65% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DayTimeDurationItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DayTimeDurationItemImpl.java index fdda3e12d..40dfa04af 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DayTimeDurationItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DayTimeDurationItemImpl.java @@ -3,20 +3,32 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.DayTimeAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDayTimeDurationItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import java.time.Duration; import edu.umd.cs.findbugs.annotations.NonNull; -class DayTimeDurationItemImpl +/** + * An implementation of a Metapath atomic item containing a duration data value + * in days, hours, and seconds. + */ +public class DayTimeDurationItemImpl extends AbstractAnyAtomicItem implements IDayTimeDurationItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public DayTimeDurationItemImpl(@NonNull Duration value) { super(value); } @@ -45,7 +57,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IDayTimeDurationItem && compareTo((IDayTimeDurationItem) obj) == 0); + || obj instanceof IDayTimeDurationItem && compareTo((IDayTimeDurationItem) obj) == 0; } private final class MapKey implements IMapKey { @@ -62,8 +74,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj || - (obj instanceof MapKey - && getKey().equals(((MapKey) obj).getKey())); + obj instanceof MapKey + && getKey().equals(((MapKey) obj).getKey()); } } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DecimalItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DecimalItemImpl.java similarity index 57% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DecimalItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DecimalItemImpl.java index 9157b4a58..d7bde671d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/DecimalItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DecimalItemImpl.java @@ -3,10 +3,11 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.DecimalAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDecimalItem; import java.math.BigDecimal; import java.math.BigInteger; @@ -14,8 +15,34 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class DecimalItemImpl +/** + * An implementation of a Metapath atomic item containing a decimal data value. + */ +public class DecimalItemImpl extends AbstractDecimalItem { + @NonNull + private static final BigDecimal BOOLEAN_TRUE = new BigDecimal("1.0"); + @NonNull + private static final BigDecimal BOOLEAN_FALSE = new BigDecimal("0.0"); + + /** + * Get the equivalent decimal value for the provided boolean value. + * + * @param value + * the boolean value + * @return the equivalent decimal value + */ + @NonNull + public static BigDecimal toBigDecimal(boolean value) { + return value ? BOOLEAN_TRUE : BOOLEAN_FALSE; + } + + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public DecimalItemImpl(@NonNull BigDecimal value) { super(value); } @@ -53,6 +80,6 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IDecimalItem && compareTo((IDecimalItem) obj) == 0); + || obj instanceof IDecimalItem && compareTo((IDecimalItem) obj) == 0; } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/EmailAddressItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/EmailAddressItemImpl.java similarity index 57% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/EmailAddressItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/EmailAddressItemImpl.java index ca284a374..964ffcdfe 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/EmailAddressItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/EmailAddressItemImpl.java @@ -3,17 +3,28 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.EmailAddressAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IEmailAddressItem; import edu.umd.cs.findbugs.annotations.NonNull; -class EmailAddressItemImpl +/** + * An implementation of a Metapath atomic item containing an email address data + * value. + */ +public class EmailAddressItemImpl extends AbstractStringItem implements IEmailAddressItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public EmailAddressItemImpl(@NonNull String value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/HostnameItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/HostnameItemImpl.java similarity index 57% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/HostnameItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/HostnameItemImpl.java index 3176da092..8aa51f65e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/HostnameItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/HostnameItemImpl.java @@ -3,17 +3,27 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.HostnameAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IHostnameItem; import edu.umd.cs.findbugs.annotations.NonNull; -class HostnameItemImpl +/** + * An implementation of a Metapath atomic item containing a hostname data value. + */ +public class HostnameItemImpl extends AbstractStringItem implements IHostnameItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public HostnameItemImpl(@NonNull String value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPv4AddressItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IPv4AddressItemImpl.java similarity index 58% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPv4AddressItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IPv4AddressItemImpl.java index 0eb50a346..a650364e6 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPv4AddressItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IPv4AddressItemImpl.java @@ -3,18 +3,30 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.IPv4AddressAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractUntypedAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIPv4AddressItem; import edu.umd.cs.findbugs.annotations.NonNull; import inet.ipaddr.ipv4.IPv4Address; -class IPv4AddressItemImpl +/** + * An implementation of a Metapath atomic item containing an IPv4 address data + * value. + */ +public class IPv4AddressItemImpl extends AbstractUntypedAtomicItem implements IIPv4AddressItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public IPv4AddressItemImpl(@NonNull IPv4Address value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPv6AddressItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IPv6AddressItemImpl.java similarity index 58% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPv6AddressItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IPv6AddressItemImpl.java index 42c03543a..e72eb917e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPv6AddressItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IPv6AddressItemImpl.java @@ -3,18 +3,30 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.IPv6AddressAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractUntypedAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IIPv6AddressItem; import edu.umd.cs.findbugs.annotations.NonNull; import inet.ipaddr.ipv6.IPv6Address; -class IPv6AddressItemImpl +/** + * An implementation of a Metapath atomic item containing an IPv6 address data + * value. + */ +public class IPv6AddressItemImpl extends AbstractUntypedAtomicItem implements IIPv6AddressItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public IPv6AddressItemImpl(@NonNull IPv6Address value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IntegerItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IntegerItemImpl.java similarity index 56% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IntegerItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IntegerItemImpl.java index 7ff1f5aff..cc4abe588 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IntegerItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/IntegerItemImpl.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.IntegerAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; @@ -12,10 +12,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class IntegerItemImpl +/** + * An implementation of a Metapath atomic item containing an integer data value. + */ +public class IntegerItemImpl extends AbstractIntegerItem { - protected IntegerItemImpl(@NonNull BigInteger value) { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ + public IntegerItemImpl(@NonNull BigInteger value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/MarkupLineItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/MarkupLineItemImpl.java similarity index 58% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/MarkupLineItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/MarkupLineItemImpl.java index 1ef4ffb98..ef6e1e912 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/MarkupLineItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/MarkupLineItemImpl.java @@ -3,18 +3,30 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLineAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractUntypedAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IMarkupItem; import edu.umd.cs.findbugs.annotations.NonNull; -class MarkupLineItemImpl +/** + * An implementation of a Metapath atomic item representing a single line Markup + * data value. + */ +public class MarkupLineItemImpl extends AbstractUntypedAtomicItem implements IMarkupItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public MarkupLineItemImpl(@NonNull MarkupLine value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/MarkupMultiLineItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/MarkupMultiLineItemImpl.java similarity index 59% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/MarkupMultiLineItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/MarkupMultiLineItemImpl.java index bbd1894ab..167d75ab5 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/MarkupMultiLineItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/MarkupMultiLineItemImpl.java @@ -3,18 +3,30 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultilineAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractUntypedAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IMarkupItem; import edu.umd.cs.findbugs.annotations.NonNull; -class MarkupMultiLineItemImpl +/** + * An implementation of a Metapath atomic item representing a multi-line Markup + * data value. + */ +public class MarkupMultiLineItemImpl extends AbstractUntypedAtomicItem implements IMarkupItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public MarkupMultiLineItemImpl(@NonNull MarkupMultiline value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/NcNameItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/NcNameItemImpl.java similarity index 59% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/NcNameItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/NcNameItemImpl.java index 1a98b075c..7b0b9a88b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/NcNameItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/NcNameItemImpl.java @@ -3,18 +3,29 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.NcNameAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.INcNameItem; import edu.umd.cs.findbugs.annotations.NonNull; +/** + * An implementation of a Metapath atomic item containing a non-colonized name + * data value. + */ @Deprecated(forRemoval = true, since = "0.7.0") -class NcNameItemImpl +public class NcNameItemImpl extends AbstractStringItem implements INcNameItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public NcNameItemImpl(@NonNull String value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/NonNegativeIntegerItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/NonNegativeIntegerItemImpl.java similarity index 53% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/NonNegativeIntegerItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/NonNegativeIntegerItemImpl.java index 9d1e97567..cdb07c15f 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/NonNegativeIntegerItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/NonNegativeIntegerItemImpl.java @@ -3,20 +3,31 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.NonNegativeIntegerAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.INonNegativeIntegerItem; import java.math.BigInteger; import edu.umd.cs.findbugs.annotations.NonNull; -class NonNegativeIntegerItemImpl +/** + * An implementation of a Metapath atomic item containing a non-negative integer + * data value. + */ +public class NonNegativeIntegerItemImpl extends AbstractIntegerItem implements INonNegativeIntegerItem { - protected NonNegativeIntegerItemImpl(@NonNull BigInteger value) { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ + public NonNegativeIntegerItemImpl(@NonNull BigInteger value) { super(value); } @@ -24,4 +35,5 @@ protected NonNegativeIntegerItemImpl(@NonNull BigInteger value) { public NonNegativeIntegerAdapter getJavaTypeAdapter() { return MetaschemaDataTypeProvider.NON_NEGATIVE_INTEGER; } + } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/PositiveIntegerItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/PositiveIntegerItemImpl.java similarity index 53% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/PositiveIntegerItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/PositiveIntegerItemImpl.java index 9f20445c7..95cec453a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/PositiveIntegerItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/PositiveIntegerItemImpl.java @@ -3,20 +3,31 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.PositiveIntegerAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IPositiveIntegerItem; import java.math.BigInteger; import edu.umd.cs.findbugs.annotations.NonNull; -class PositiveIntegerItemImpl +/** + * An implementation of a Metapath atomic item containing a positive integer + * data value. + */ +public class PositiveIntegerItemImpl extends AbstractIntegerItem implements IPositiveIntegerItem { - protected PositiveIntegerItemImpl(@NonNull BigInteger value) { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ + public PositiveIntegerItemImpl(@NonNull BigInteger value) { super(value); } @@ -24,4 +35,5 @@ protected PositiveIntegerItemImpl(@NonNull BigInteger value) { public PositiveIntegerAdapter getJavaTypeAdapter() { return MetaschemaDataTypeProvider.POSITIVE_INTEGER; } + } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/StringItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/StringItemImpl.java similarity index 61% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/StringItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/StringItemImpl.java index fea0a27c6..2794093df 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/StringItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/StringItemImpl.java @@ -3,16 +3,25 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.StringAdapter; import edu.umd.cs.findbugs.annotations.NonNull; -class StringItemImpl +/** + * An implementation of a Metapath atomic item containing a text data value. + */ +public class StringItemImpl extends AbstractStringItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public StringItemImpl(@NonNull String value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/TokenItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/TokenItemImpl.java similarity index 57% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/TokenItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/TokenItemImpl.java index 185404413..98dd86349 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/TokenItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/TokenItemImpl.java @@ -3,17 +3,28 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.TokenAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.ITokenItem; import edu.umd.cs.findbugs.annotations.NonNull; -class TokenItemImpl +/** + * An implementation of a Metapath atomic item containing a text token data + * value. + */ +public class TokenItemImpl extends AbstractStringItem implements ITokenItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public TokenItemImpl(@NonNull String value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UriReferenceItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UriReferenceItemImpl.java similarity index 58% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UriReferenceItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UriReferenceItemImpl.java index 2e0b6c1a5..e50775222 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UriReferenceItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UriReferenceItemImpl.java @@ -3,19 +3,30 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.UriReferenceAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IUriReferenceItem; import java.net.URI; import edu.umd.cs.findbugs.annotations.NonNull; -class UriReferenceItemImpl +/** + * An implementation of a Metapath atomic item containing a URI reference data + * value. + */ +public class UriReferenceItemImpl extends AbstractUriItem implements IUriReferenceItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public UriReferenceItemImpl(@NonNull URI value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java similarity index 70% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java index 69dbdf8b7..ef3c3bdde 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/UuidItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java @@ -3,10 +3,13 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IStringItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IUuidItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import gov.nist.secauto.metaschema.core.util.ObjectUtils; @@ -14,10 +17,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class UuidItemImpl +/** + * An implementation of a Metapath atomic item containing a UUID data value. + */ +public class UuidItemImpl extends AbstractAnyAtomicItem implements IUuidItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public UuidItemImpl(@NonNull UUID value) { super(value); } @@ -51,7 +63,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IStringItem && compareTo((IStringItem) obj) == 0); + || obj instanceof IStringItem && compareTo((IStringItem) obj) == 0; } @Override @@ -74,8 +86,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj || - (obj instanceof MapKey - && getKey().asUuid().equals(((MapKey) obj).getKey().asUuid())); + obj instanceof MapKey + && getKey().asUuid().equals(((MapKey) obj).getKey().asUuid()); } } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/YearMonthDurationItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/YearMonthDurationItemImpl.java similarity index 66% rename from core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/YearMonthDurationItemImpl.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/YearMonthDurationItemImpl.java index 213acb802..f572a2281 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/YearMonthDurationItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/YearMonthDurationItemImpl.java @@ -3,10 +3,12 @@ * SPDX-License-Identifier: CC0-1.0 */ -package gov.nist.secauto.metaschema.core.metapath.item.atomic; +package gov.nist.secauto.metaschema.core.metapath.item.atomic.impl; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; import gov.nist.secauto.metaschema.core.datatype.adapter.YearMonthAdapter; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.AbstractAnyAtomicItem; +import gov.nist.secauto.metaschema.core.metapath.item.atomic.IYearMonthDurationItem; import gov.nist.secauto.metaschema.core.metapath.item.function.IMapKey; import java.time.Period; @@ -14,10 +16,20 @@ import edu.umd.cs.findbugs.annotations.NonNull; -class YearMonthDurationItemImpl +/** + * An implementation of a Metapath atomic item containing a duration data value + * in years and months. + */ +public class YearMonthDurationItemImpl extends AbstractAnyAtomicItem implements IYearMonthDurationItem { + /** + * Construct a new item with the provided {@code value}. + * + * @param value + * the value to wrap + */ public YearMonthDurationItemImpl(@NonNull Period value) { super(value); } @@ -46,7 +58,7 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj - || (obj instanceof IYearMonthDurationItem && compareTo((IYearMonthDurationItem) obj) == 0); + || obj instanceof IYearMonthDurationItem && compareTo((IYearMonthDurationItem) obj) == 0; } private final class MapKey implements IMapKey { @@ -63,8 +75,8 @@ public int hashCode() { @Override public boolean equals(Object obj) { return this == obj || - (obj instanceof MapKey - && getKey().equals(((MapKey) obj).getKey())); + obj instanceof MapKey + && getKey().equals(((MapKey) obj).getKey()); } } } diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java index 8da0e03a5..306c421dc 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java @@ -6,6 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.function.library; import static gov.nist.secauto.metaschema.core.metapath.TestUtils.decimal; +import static gov.nist.secauto.metaschema.core.metapath.TestUtils.integer; import gov.nist.secauto.metaschema.core.metapath.ISequence; import gov.nist.secauto.metaschema.core.metapath.item.atomic.INumericItem; @@ -25,8 +26,8 @@ class FnCeilingTest private static Stream provideValues() { return Stream.of( - Arguments.of(decimal("11"), decimal("10.5")), - Arguments.of(decimal("-10"), decimal("-10.5"))); + Arguments.of(integer(11), decimal("10.5")), + Arguments.of(integer(-10), decimal("-10.5"))); } @ParameterizedTest From 2e7ed2e760ee442583b5cc7424371873b4aa876d Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Wed, 13 Nov 2024 20:00:34 -0500 Subject: [PATCH 03/20] Added more Javadocs. --- .../metaschema/core/MetaschemaConstants.java | 3 +++ .../core/datatype/markup/MarkupLine.java | 2 +- .../markup/flexmark/AstCollectingVisitor.java | 6 ++++- .../FixedEmphasisDelimiterProcessor.java | 4 ++- .../flexmark/FlexmarkConfiguration.java | 25 +++++++++++++++++-- .../markup/flexmark/FlexmarkFactory.java | 2 +- .../flexmark/HtmlCodeRenderExtension.java | 11 ++++---- .../flexmark/HtmlQuoteTagExtension.java | 9 ++++++- .../markup/flexmark/IMarkupVisitor.java | 9 +++++++ .../markup/flexmark/IMarkupWriter.java | 9 +++++++ .../flexmark/InsertAnchorExtension.java | 15 +++++++---- .../markup/flexmark/MarkupXmlEventWriter.java | 3 +++ .../flexmark/MarkupXmlStreamWriter.java | 4 ++- .../flexmark/SuppressPTagExtension.java | 6 ++++- 14 files changed, 89 insertions(+), 19 deletions(-) diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/MetaschemaConstants.java b/core/src/main/java/gov/nist/secauto/metaschema/core/MetaschemaConstants.java index 0456bd903..43ad55978 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/MetaschemaConstants.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/MetaschemaConstants.java @@ -11,6 +11,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A collection of constant values related to Metaschema handling. + */ public final class MetaschemaConstants { /** * This is the namespace used by Metaschema in formats that require or use a diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java index 77468d545..9e80a4b79 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/MarkupLine.java @@ -48,7 +48,7 @@ private static DataSet newParserOptions() { options.set(Parser.LIST_BLOCK_PARSER, false); options.set(HtmlRenderer.SUPPRESS_HTML_BLOCKS, true); - Collection currentExtensions = Parser.EXTENSIONS.get(FlexmarkConfiguration.FLEXMARK_CONFIG); + Collection currentExtensions = Parser.EXTENSIONS.get(FlexmarkConfiguration.instance()); List extensions = new LinkedList<>(currentExtensions); extensions.add(SuppressPTagExtension.newInstance()); Parser.EXTENSIONS.set(options, extensions); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/AstCollectingVisitor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/AstCollectingVisitor.java index c97b017b2..1787b7d7d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/AstCollectingVisitor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/AstCollectingVisitor.java @@ -12,9 +12,13 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * This class supports building a text-based representation of a Markup node + * tree. + */ public final class AstCollectingVisitor extends NodeVisitorBase { - public static final String EOL = "\n"; + private static final String EOL = System.lineSeparator(); @SuppressWarnings("PMD.AvoidStringBufferField") // short lived private final StringBuilder strBuilder; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FixedEmphasisDelimiterProcessor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FixedEmphasisDelimiterProcessor.java index 946d697cc..e3226917c 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FixedEmphasisDelimiterProcessor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FixedEmphasisDelimiterProcessor.java @@ -17,7 +17,9 @@ /** * Provides a temporary fix for the broken {@link EmphasisDelimiterProcessor} in - * Flexmark. + * Flexmark. See the + * GitHub pull + * request. */ public class FixedEmphasisDelimiterProcessor extends AsteriskDelimiterProcessor { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkConfiguration.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkConfiguration.java index 52013359d..92b447da8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkConfiguration.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkConfiguration.java @@ -21,20 +21,41 @@ import com.vladsch.flexmark.util.format.options.ListBulletMarker; import com.vladsch.flexmark.util.misc.Extension; +import gov.nist.secauto.metaschema.core.util.ObjectUtils; + import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +import nl.talsmasoftware.lazy4j.Lazy; +/** + * This class manages a shared Flexmark configuration for use by other + * implementations. + */ public final class FlexmarkConfiguration { @NonNull private static final ParserEmulationProfile PARSER_PROFILE = ParserEmulationProfile.COMMONMARK_0_29; + /** + * The shared Flexmark configuration. + */ @NonNull - public static final DataSet FLEXMARK_CONFIG = initFlexmarkConfig(); + private static final Lazy FLEXMARK_CONFIG + = ObjectUtils.notNull(Lazy.lazy(FlexmarkConfiguration::initFlexmarkConfig)); + + /** + * Get the singleton configuration instance. + * + * @return the configuration + */ + @NonNull + public static DataSet instance() { + return ObjectUtils.notNull(FLEXMARK_CONFIG.get()); + } @SuppressWarnings("null") @NonNull @@ -133,7 +154,7 @@ private static DataSet initFlexmarkConfig() { * @return the configuration */ public static DataSet newFlexmarkConfig(@Nullable DataHolder options) { - return options == null ? FLEXMARK_CONFIG : DataSet.merge(FLEXMARK_CONFIG, options); + return options == null ? instance() : DataSet.merge(instance(), options); } private FlexmarkConfiguration() { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkFactory.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkFactory.java index 3d8a44947..670ba9371 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkFactory.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/FlexmarkFactory.java @@ -58,7 +58,7 @@ public static FlexmarkFactory newInstance(@NonNull DataHolder config) { } private FlexmarkFactory() { - this(FlexmarkConfiguration.FLEXMARK_CONFIG); + this(FlexmarkConfiguration.instance()); } @SuppressWarnings("null") diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlCodeRenderExtension.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlCodeRenderExtension.java index ae356bc38..b057a4555 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlCodeRenderExtension.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlCodeRenderExtension.java @@ -32,6 +32,9 @@ import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +/** + * Ensures code blocks are properly handled. + */ public class HtmlCodeRenderExtension implements HtmlRenderer.HtmlRendererExtension { private static final Pattern EOL_PATTERN = Pattern.compile("\r\n|\r|\n"); @@ -79,12 +82,10 @@ private void render( // NOPMD actually used in lambda boolean customTag = htmlOptions.codeStyleHtmlOpen != null || htmlOptions.codeStyleHtmlClose != null; if (customTag) { html.raw(ObjectUtils.notNull(htmlOptions.codeStyleHtmlOpen)); + } else if (context.getHtmlOptions().sourcePositionParagraphLines) { + html.withAttr().tag("code"); } else { - if (context.getHtmlOptions().sourcePositionParagraphLines) { - html.withAttr().tag("code"); - } else { - html.srcPos(node.getText()).withAttr().tag("code"); - } + html.srcPos(node.getText()).withAttr().tag("code"); } if (codeSoftLineBreaks && !htmlOptions.isSoftBreakAllSpaces) { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java index bba9165b8..563ec7278 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java @@ -36,6 +36,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +/** + * Adds support for the use of "q" tags in HTML to replace quotation marks. + * These are translated to double quotes in Markdown. + */ public class HtmlQuoteTagExtension implements Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension, FlexmarkHtmlConverter.HtmlConverterExtension { @@ -78,7 +82,7 @@ static class QTagNodeRenderer implements NodeRenderer { @Override public @Nullable - Set> getNodeRenderingHandlers() { + Set> getNodeRenderingHandlers() { return Collections.singleton( new NodeRenderingHandler<>(DoubleQuoteNode.class, this::render)); } @@ -154,6 +158,9 @@ public HtmlNodeRenderer apply(DataHolder options) { } + /** + * A Flexmark node implementation representing a quotation mark. + */ public static class DoubleQuoteNode extends TypographicQuotes { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupVisitor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupVisitor.java index e20741280..286de8e0d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupVisitor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupVisitor.java @@ -10,6 +10,15 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +/** + * Support for visiting a Flexmark syntax tree. + * + * @param + * the Java type of sync to write to + * @param + * the Java type of exception that can be thrown when a writing error + * occurs + */ @SuppressFBWarnings("THROWS_METHOD_THROWS_CLAUSE_THROWABLE") public interface IMarkupVisitor { /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupWriter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupWriter.java index df01dc58f..aa2566645 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupWriter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/IMarkupWriter.java @@ -40,6 +40,15 @@ import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +/** + * A common interface for writing markup to some form of an output sync. + * + * @param + * the Java type of sync to write to + * @param + * the Java type of exception that can be thrown when a writing error + * occurs + */ @SuppressFBWarnings(value = "THROWS_METHOD_THROWS_CLAUSE_THROWABLE", justification = "There is a need to support varying exceptions from multiple stream writers") public interface IMarkupWriter { // NOPMD diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/InsertAnchorExtension.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/InsertAnchorExtension.java index cf12d9c35..c07255ba4 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/InsertAnchorExtension.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/InsertAnchorExtension.java @@ -50,12 +50,16 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * This adds support for insert anchors, which are used in OSCAL statements + * currently, but can be used more generally in other OSCAL models. + */ public class InsertAnchorExtension implements Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension, Formatter.FormatterExtension, FlexmarkHtmlConverter.HtmlConverterExtension { - public static final DataKey ENABLE_INLINE_INSERT_ANCHORS + private static final DataKey ENABLE_INLINE_INSERT_ANCHORS = new DataKey<>("ENABLE_INLINE_INSERT_ANCHORS", true); - public static final DataKey ENABLE_RENDERING = new DataKey<>("ENABLE_RENDERING", true); + private static final DataKey ENABLE_RENDERING = new DataKey<>("ENABLE_RENDERING", true); /** * Construct a new extension instance. @@ -276,6 +280,9 @@ public HtmlNodeRenderer apply(DataHolder options) { } } + /** + * The flexmark node for an insert anchor. + */ public static class InsertAnchorNode extends Node { @@ -343,9 +350,7 @@ public void setIdReference(@NonNull BasedSequence idReference) { @Override @NonNull public BasedSequence[] getSegments() { - @NonNull - BasedSequence[] retval = { getType(), getIdReference() }; - return retval; + return new BasedSequence[] { getType(), getIdReference() }; } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlEventWriter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlEventWriter.java index 006a30a4f..1a0f9a5de 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlEventWriter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlEventWriter.java @@ -27,6 +27,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Provides support for writing Flexmark markup nodes to an XML event stream. + */ public class MarkupXmlEventWriter extends AbstractMarkupWriter { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlStreamWriter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlStreamWriter.java index 86831d0bd..f30c3d537 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlStreamWriter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/MarkupXmlStreamWriter.java @@ -17,7 +17,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; -// TODO: Is this orphaned code needed? +/** + * Provides support for writing Flexmark markup nodes to an XML stream. + */ public class MarkupXmlStreamWriter extends AbstractMarkupWriter { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java index 683c75720..54cae7a3a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java @@ -21,6 +21,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; +/** + * Provides the ability to suppress paragraph "p" tags for single line markup + * generation. + */ public class SuppressPTagExtension implements HtmlRenderer.HtmlRendererExtension { @@ -47,7 +51,7 @@ static class PTagNodeRenderer implements NodeRenderer { @Override public @Nullable - Set> getNodeRenderingHandlers() { + Set> getNodeRenderingHandlers() { return Collections.singleton( new NodeRenderingHandler<>(Paragraph.class, this::render)); } From 69d9925af5e0e5b33500aee543d030a88b301e96 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Wed, 13 Nov 2024 20:07:37 -0500 Subject: [PATCH 04/20] Refactored names of temporal implementation classes. Adjusted Javadocs to provide more details. --- .../core/datatype/adapter/DateAdapter.java | 16 ++++++++-------- .../core/datatype/adapter/DateTimeAdapter.java | 18 +++++++++--------- .../object/AbstractAmbiguousTemporal.java | 3 +++ .../object/{Date.java => AmbiguousDate.java} | 16 +++++++++++----- .../{DateTime.java => AmbiguousDateTime.java} | 17 ++++++++++++----- .../core/metapath/item/atomic/IDateItem.java | 4 ++-- .../metapath/item/atomic/IDateTimeItem.java | 4 ++-- .../impl/DateTimeWithoutTimeZoneItemImpl.java | 6 +++--- .../impl/DateWithoutTimeZoneItemImpl.java | 6 +++--- .../secauto/metaschema/core/package-info.java | 10 ++++++++++ 10 files changed, 63 insertions(+), 37 deletions(-) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/{Date.java => AmbiguousDate.java} (57%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/{DateTime.java => AmbiguousDateTime.java} (56%) create mode 100644 core/src/main/java/gov/nist/secauto/metaschema/core/package-info.java diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java index 4498f11f4..ab2c79799 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapter.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; import gov.nist.secauto.metaschema.core.datatype.AbstractCustomJavaDataTypeAdapter; -import gov.nist.secauto.metaschema.core.datatype.object.Date; +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDate; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; @@ -33,7 +33,7 @@ * data type. */ public class DateAdapter - extends AbstractCustomJavaDataTypeAdapter { + extends AbstractCustomJavaDataTypeAdapter { @NonNull private static final List NAMES = ObjectUtils.notNull( List.of(new QName(MetapathConstants.NS_METAPATH.toASCIIString(), "date"))); @@ -48,7 +48,7 @@ public class DateAdapter + "(Z|[+-][0-9]{2}:[0-9]{2})?$")); DateAdapter() { - super(Date.class); + super(AmbiguousDate.class); } @Override @@ -62,7 +62,7 @@ public JsonFormatTypes getJsonRawType() { } @Override - public Date parse(String value) { + public AmbiguousDate parse(String value) { Matcher matcher = DATE_TIMEZONE.matcher(value); if (!matcher.matches()) { throw new IllegalArgumentException("Invalid date: " + value); @@ -72,12 +72,12 @@ public Date parse(String value) { = String.format("%sT00:00:00%s", matcher.group(1), matcher.group(2) == null ? "" : matcher.group(2)); try { TemporalAccessor accessor = DateFormats.DATE_TIME_WITH_TZ.parse(parseValue); - return new Date(ObjectUtils.notNull(ZonedDateTime.from(accessor)), true); // NOPMD - readability + return new AmbiguousDate(ObjectUtils.notNull(ZonedDateTime.from(accessor)), true); // NOPMD - readability } catch (DateTimeParseException ex) { try { TemporalAccessor accessor = DateFormats.DATE_TIME_WITHOUT_TZ.parse(parseValue); LocalDate date = LocalDate.from(accessor); - return new Date(ObjectUtils.notNull(ZonedDateTime.of(date, LocalTime.MIN, ZoneOffset.UTC)), false); + return new AmbiguousDate(ObjectUtils.notNull(ZonedDateTime.of(date, LocalTime.MIN, ZoneOffset.UTC)), false); } catch (DateTimeParseException ex2) { IllegalArgumentException newEx = new IllegalArgumentException(ex2.getLocalizedMessage(), ex2); newEx.addSuppressed(ex); @@ -88,7 +88,7 @@ public Date parse(String value) { @Override public String asString(Object obj) { - Date value = (Date) obj; + AmbiguousDate value = (AmbiguousDate) obj; return ObjectUtils.notNull(value.hasTimeZone() ? DateFormats.DATE_WITH_TZ.format(value.getValue()) : DateFormats.DATE_WITHOUT_TZ.format(value.getValue())); @@ -101,7 +101,7 @@ public Class getItemClass() { @Override public IDateItem newItem(Object value) { - Date item = toValue(value); + AmbiguousDate item = toValue(value); return IDateItem.valueOf(item); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java index 5674dcf09..7e2dd7929 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java @@ -8,7 +8,7 @@ import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatTypes; import gov.nist.secauto.metaschema.core.datatype.AbstractCustomJavaDataTypeAdapter; -import gov.nist.secauto.metaschema.core.datatype.object.DateTime; +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDateTime; import gov.nist.secauto.metaschema.core.metapath.MetapathConstants; import gov.nist.secauto.metaschema.core.metapath.item.atomic.IDateTimeItem; import gov.nist.secauto.metaschema.core.util.ObjectUtils; @@ -29,7 +29,7 @@ * data type. */ public class DateTimeAdapter - extends AbstractCustomJavaDataTypeAdapter { + extends AbstractCustomJavaDataTypeAdapter { @NonNull private static final List NAMES = ObjectUtils.notNull( List.of( @@ -38,7 +38,7 @@ public class DateTimeAdapter new QName(MetapathConstants.NS_METAPATH.toASCIIString(), "dateTime"))); DateTimeAdapter() { - super(DateTime.class); + super(AmbiguousDateTime.class); } @Override @@ -52,16 +52,16 @@ public JsonFormatTypes getJsonRawType() { } @Override - public DateTime parse(String value) { - DateTime retval; + public AmbiguousDateTime parse(String value) { + AmbiguousDateTime retval; try { - retval = new DateTime( + retval = new AmbiguousDateTime( ObjectUtils.notNull(ZonedDateTime.from(DateFormats.DATE_TIME_WITH_TZ.parse(value))), true); } catch (DateTimeParseException ex) { try { LocalDateTime dateTime = LocalDateTime.from(DateFormats.DATE_TIME_WITHOUT_TZ.parse(value)); - retval = new DateTime( + retval = new AmbiguousDateTime( ObjectUtils.notNull(ZonedDateTime.of(dateTime, ZoneOffset.UTC)), false); } catch (DateTimeParseException ex2) { @@ -75,7 +75,7 @@ public DateTime parse(String value) { @Override public String asString(Object obj) { - DateTime value = (DateTime) obj; + AmbiguousDateTime value = (AmbiguousDateTime) obj; return ObjectUtils.notNull(value.hasTimeZone() ? DateFormats.DATE_TIME_WITH_TZ.format(value.getValue()) : DateFormats.DATE_TIME_WITHOUT_TZ.format(value.getValue())); @@ -88,7 +88,7 @@ public Class getItemClass() { @Override public IDateTimeItem newItem(Object value) { - DateTime item = toValue(value); + AmbiguousDateTime item = toValue(value); return IDateTimeItem.valueOf(item); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AbstractAmbiguousTemporal.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AbstractAmbiguousTemporal.java index 303ad3600..bbe5dc2dc 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AbstractAmbiguousTemporal.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AbstractAmbiguousTemporal.java @@ -12,6 +12,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** + * Implementations of this class represent a temporal value which may not have a + * timezone making it ambiguous as a point/window in time. + *

* Metaschema has a need to represent dates and times that allow for an * ambiguous time zone. This is due to some models not requiring a time zone as * part of a date/time. An ambiguous dateTime allows a time zone to be inferred, diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/Date.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AmbiguousDate.java similarity index 57% rename from core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/Date.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AmbiguousDate.java index 6a26460ef..a412a90ee 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/Date.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AmbiguousDate.java @@ -9,12 +9,18 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public class Date // NOPMD - intentional - extends AbstractAmbiguousTemporal { +/** + * Represents a date value which may not have a timezone making it ambiguous as + * a window in time. + */ +public class AmbiguousDate + extends AbstractAmbiguousTemporal { /** * Construct a new date object. This type supports ambiguous dates that were * provided without a time zone. + *

+ * The date value will be ambiguous if the {@code hasTimeZone} is {@code false}. * * @param value * the date value @@ -22,12 +28,12 @@ public class Date // NOPMD - intentional * {@code true} if the date is intended to have an associated time zone * or {@code false} otherwise */ - public Date(@NonNull ZonedDateTime value, boolean hasTimeZone) { + public AmbiguousDate(@NonNull ZonedDateTime value, boolean hasTimeZone) { super(value, hasTimeZone); } @Override - public Date copy() { - return new Date(getValue(), hasTimeZone()); + public AmbiguousDate copy() { + return new AmbiguousDate(getValue(), hasTimeZone()); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/DateTime.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AmbiguousDateTime.java similarity index 56% rename from core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/DateTime.java rename to core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AmbiguousDateTime.java index 197f7ecce..932646e68 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/DateTime.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/object/AmbiguousDateTime.java @@ -9,12 +9,19 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public class DateTime - extends AbstractAmbiguousTemporal { +/** + * Represents a date/time value which may not have a timezone making it + * ambiguous as a point in time. + */ +public class AmbiguousDateTime + extends AbstractAmbiguousTemporal { /** * Construct a new date/time object. This type supports ambiguous dates/times * that were provided without a time zone. + *

+ * The date/time value will be ambiguous if the {@code hasTimeZone} is + * {@code false}. * * @param value * the date/time value @@ -22,12 +29,12 @@ public class DateTime * {@code true} if the date/time is intended to have an associated time * zone or {@code false} otherwise */ - public DateTime(@NonNull ZonedDateTime value, boolean hasTimeZone) { + public AmbiguousDateTime(@NonNull ZonedDateTime value, boolean hasTimeZone) { super(value, hasTimeZone); } @Override - public DateTime copy() { - return new DateTime(getValue(), hasTimeZone()); + public AmbiguousDateTime copy() { + return new AmbiguousDateTime(getValue(), hasTimeZone()); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java index 9984156fa..5fb9bbc66 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java @@ -6,7 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; -import gov.nist.secauto.metaschema.core.datatype.object.Date; +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDate; import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DateWithTimeZoneItemImpl; @@ -52,7 +52,7 @@ static IDateItem valueOf(@NonNull String value) { * @return the new item */ @NonNull - static IDateItem valueOf(@NonNull Date value) { + static IDateItem valueOf(@NonNull AmbiguousDate value) { return new DateWithoutTimeZoneItemImpl(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java index 5daa1b735..bf8b0290b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java @@ -6,7 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; -import gov.nist.secauto.metaschema.core.datatype.object.DateTime; +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDateTime; import gov.nist.secauto.metaschema.core.metapath.InvalidTypeMetapathException; import gov.nist.secauto.metaschema.core.metapath.function.InvalidValueForCastFunctionException; import gov.nist.secauto.metaschema.core.metapath.item.atomic.impl.DateTimeWithTimeZoneItemImpl; @@ -49,7 +49,7 @@ static IDateTimeItem valueOf(@NonNull String value) { * @return the new item */ @NonNull - static IDateTimeItem valueOf(@NonNull DateTime value) { + static IDateTimeItem valueOf(@NonNull AmbiguousDateTime value) { return new DateTimeWithoutTimeZoneItemImpl(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java index 8a9241d68..495166af9 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateTimeWithoutTimeZoneItemImpl.java @@ -7,7 +7,7 @@ import gov.nist.secauto.metaschema.core.datatype.adapter.DateTimeAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; -import gov.nist.secauto.metaschema.core.datatype.object.DateTime; +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDateTime; import java.time.ZonedDateTime; @@ -18,7 +18,7 @@ * that may not have an explicit timezone. */ public class DateTimeWithoutTimeZoneItemImpl - extends AbstractDateTimeItem { + extends AbstractDateTimeItem { /** * Construct a new item with the provided {@code value}. @@ -26,7 +26,7 @@ public class DateTimeWithoutTimeZoneItemImpl * @param value * the value to wrap */ - public DateTimeWithoutTimeZoneItemImpl(@NonNull DateTime value) { + public DateTimeWithoutTimeZoneItemImpl(@NonNull AmbiguousDateTime value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java index fc2948fb5..86f79a4c0 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/DateWithoutTimeZoneItemImpl.java @@ -7,7 +7,7 @@ import gov.nist.secauto.metaschema.core.datatype.adapter.DateAdapter; import gov.nist.secauto.metaschema.core.datatype.adapter.MetaschemaDataTypeProvider; -import gov.nist.secauto.metaschema.core.datatype.object.Date; +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDate; import java.time.ZonedDateTime; @@ -18,7 +18,7 @@ * may not have an explicit timezone. */ public class DateWithoutTimeZoneItemImpl - extends AbstractDateItem { + extends AbstractDateItem { /** * Construct a new item with the provided {@code value}. @@ -26,7 +26,7 @@ public class DateWithoutTimeZoneItemImpl * @param value * the value to wrap */ - public DateWithoutTimeZoneItemImpl(@NonNull Date value) { + public DateWithoutTimeZoneItemImpl(@NonNull AmbiguousDate value) { super(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/package-info.java b/core/src/main/java/gov/nist/secauto/metaschema/core/package-info.java new file mode 100644 index 000000000..b3733e1a0 --- /dev/null +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/package-info.java @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: none + * SPDX-License-Identifier: CC0-1.0 + */ + +/** + * Core support for handling Metaschema-based models. + */ + +package gov.nist.secauto.metaschema.core; From 6504a02ea9b3d454c0696d3a1bdb5bd59ec993b4 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Thu, 14 Nov 2024 00:09:06 -0500 Subject: [PATCH 05/20] Removed some unused constants and added more Javadocs. --- .../metaschema/core/metapath/EQNameUtils.java | 3 + .../core/metapath/ICollectionValue.java | 3 + .../metaschema/core/metapath/IPrintable.java | 4 ++ .../core/metapath/MetapathConstants.java | 60 +++++++++++++++---- .../core/metapath/MetapathExpression.java | 7 ++- .../core/metapath/StaticContext.java | 20 +++---- .../function/library/CastFunction.java | 6 ++ .../library/DefaultFunctionLibrary.java | 1 + .../metapath/function/library/MapEntry.java | 2 +- .../core/model/xml/ModuleLoader.java | 19 +++--- 10 files changed, 89 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/EQNameUtils.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/EQNameUtils.java index e62fb0a00..82b173318 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/EQNameUtils.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/EQNameUtils.java @@ -13,6 +13,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Utilities for managing qualified names. + */ public final class EQNameUtils { private static final Pattern URI_QUALIFIED_NAME = Pattern.compile("^Q\\{([^{}]*)\\}(.+)$"); private static final Pattern LEXICAL_NAME = Pattern.compile("^(?:([^:]+):)?(.+)$"); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/ICollectionValue.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/ICollectionValue.java index 834276250..6f6b5dfd6 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/ICollectionValue.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/ICollectionValue.java @@ -12,6 +12,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * A data value that can be a value in a Metapath array or map. + */ public interface ICollectionValue { /** * Get the collection value as a sequence. diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/IPrintable.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/IPrintable.java index 7ff7c7b87..cb63888fc 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/IPrintable.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/IPrintable.java @@ -7,6 +7,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Identifies the implementation as being able to produce a string value for + * output. + */ public interface IPrintable { /** * Get the string value. diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathConstants.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathConstants.java index 6dc3652d9..b9c47466b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathConstants.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathConstants.java @@ -9,48 +9,84 @@ import java.net.URI; -import javax.xml.XMLConstants; - import edu.umd.cs.findbugs.annotations.NonNull; /** - * Provides constant values used in Metapath. + * Provides constant values for use in Metapath. */ @SuppressWarnings("PMD.DataClass") public final class MetapathConstants { + /** + * The namespace URI for Metapath data types and built-in casting functions. + */ @NonNull public static final URI NS_METAPATH = ObjectUtils.requireNonNull( URI.create("http://csrc.nist.gov/ns/metaschema/metapath")); - @NonNull - public static final URI NS_XML_SCHEMA = ObjectUtils.requireNonNull( - URI.create(XMLConstants.W3C_XML_SCHEMA_NS_URI)); + /** + * The namespace URI for Metapath built-in functions. + * + * @see #PREFIX_METAPATH for the default prefix for this namespace + */ @NonNull public static final URI NS_METAPATH_FUNCTIONS = ObjectUtils.requireNonNull( URI.create("http://csrc.nist.gov/ns/metaschema/metapath-functions")); + /** + * The namespace URI for Metapath math-related built-in functions. + * + * @see #PREFIX_METAPATH_FUNCTIONS_MATH for the default prefix for this + * namespace + */ @NonNull public static final URI NS_METAPATH_FUNCTIONS_MATH = ObjectUtils.requireNonNull( URI.create(NS_METAPATH_FUNCTIONS + "/math")); + /** + * The namespace URI for Metapath array-related built-in functions. + * + * @see #PREFIX_METAPATH_FUNCTIONS_ARRAY for the default prefix for this + * namespace + */ @NonNull public static final URI NS_METAPATH_FUNCTIONS_ARRAY = ObjectUtils.requireNonNull( URI.create(NS_METAPATH_FUNCTIONS + "/array")); + /** + * The namespace URI for Metapath map-related built-in functions. + * + * @see #PREFIX_METAPATH_FUNCTIONS_MAP for the default prefix for this namespace + */ @NonNull public static final URI NS_METAPATH_FUNCTIONS_MAP = ObjectUtils.requireNonNull( URI.create(NS_METAPATH_FUNCTIONS + "/map")); + /** + * The namespace URI for Metapath extension built-in functions. + */ @NonNull public static final URI NS_METAPATH_FUNCTIONS_EXTENDED = NS_METAPATH_FUNCTIONS; + /** + * The namespace prefix for Metapath data types and built-in casting functions. + */ @NonNull public static final String PREFIX_METAPATH = "meta"; + /** + * The namespace prefix for Metapath built-in functions. + */ @NonNull - public static final String PREFIX_XML_SCHEMA = "xs"; - @NonNull - public static final String PREFIX_XPATH_FUNCTIONS = "mp"; + public static final String PREFIX_METAPATH_FUNCTIONS = "mp"; + /** + * The namespace prefix for Metapath math-related built-in functions. + */ @NonNull - public static final String PREFIX_XPATH_FUNCTIONS_MATH = "math"; + public static final String PREFIX_METAPATH_FUNCTIONS_MATH = "math"; + /** + * The namespace prefix for Metapath array-related built-in functions. + */ @NonNull - public static final String PREFIX_XPATH_FUNCTIONS_ARRAY = "array"; + public static final String PREFIX_METAPATH_FUNCTIONS_ARRAY = "array"; + /** + * The namespace prefix for Metapath map-related built-in functions. + */ @NonNull - public static final String PREFIX_XPATH_FUNCTIONS_MAP = "map"; + public static final String PREFIX_METAPATH_FUNCTIONS_MAP = "map"; private MetapathConstants() { // disable construction diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathExpression.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathExpression.java index 2cdcfdaed..88eb925a0 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathExpression.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/MetapathExpression.java @@ -47,7 +47,9 @@ "PMD.CouplingBetweenObjects" // necessary since this class aggregates functionality }) public class MetapathExpression { - + /** + * Identifies the expected type for a Metapath evaluation result. + */ public enum ResultType { /** * The result is expected to be a {@link BigDecimal} value. @@ -73,6 +75,9 @@ public enum ResultType { private static final Logger LOGGER = LogManager.getLogger(MetapathExpression.class); + /** + * The Metapath expression identifying the current context node. + */ @NonNull public static final MetapathExpression CONTEXT_NODE = new MetapathExpression(".", ContextItem.instance(), StaticContext.instance()); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/StaticContext.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/StaticContext.java index 13bce12ee..6baaee7dd 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/StaticContext.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/StaticContext.java @@ -37,19 +37,16 @@ public final class StaticContext { MetapathConstants.PREFIX_METAPATH, MetapathConstants.NS_METAPATH); knownNamespaces.put( - MetapathConstants.PREFIX_XML_SCHEMA, - MetapathConstants.NS_XML_SCHEMA); - knownNamespaces.put( - MetapathConstants.PREFIX_XPATH_FUNCTIONS, + MetapathConstants.PREFIX_METAPATH_FUNCTIONS, MetapathConstants.NS_METAPATH_FUNCTIONS); knownNamespaces.put( - MetapathConstants.PREFIX_XPATH_FUNCTIONS_MATH, + MetapathConstants.PREFIX_METAPATH_FUNCTIONS_MATH, MetapathConstants.NS_METAPATH_FUNCTIONS_MATH); knownNamespaces.put( - MetapathConstants.PREFIX_XPATH_FUNCTIONS_ARRAY, + MetapathConstants.PREFIX_METAPATH_FUNCTIONS_ARRAY, MetapathConstants.NS_METAPATH_FUNCTIONS_ARRAY); knownNamespaces.put( - MetapathConstants.PREFIX_XPATH_FUNCTIONS_MAP, + MetapathConstants.PREFIX_METAPATH_FUNCTIONS_MAP, MetapathConstants.NS_METAPATH_FUNCTIONS_MAP); WELL_KNOWN_NAMESPACES = CollectionUtil.unmodifiableMap(knownNamespaces); @@ -362,7 +359,7 @@ public static Builder builder() { * A builder used to generate the static context. */ public static final class Builder { - public boolean useWildcardWhenNamespaceNotDefaulted; // false + private boolean useWildcardWhenNamespaceNotDefaulted; // false @Nullable private URI baseUri; @NonNull @@ -377,13 +374,10 @@ private Builder() { MetapathConstants.PREFIX_METAPATH, MetapathConstants.NS_METAPATH); namespaces.put( - MetapathConstants.PREFIX_XML_SCHEMA, - MetapathConstants.NS_XML_SCHEMA); - namespaces.put( - MetapathConstants.PREFIX_XPATH_FUNCTIONS, + MetapathConstants.PREFIX_METAPATH_FUNCTIONS, MetapathConstants.NS_METAPATH_FUNCTIONS); namespaces.put( - MetapathConstants.PREFIX_XPATH_FUNCTIONS_MATH, + MetapathConstants.PREFIX_METAPATH_FUNCTIONS_MATH, MetapathConstants.NS_METAPATH_FUNCTIONS_MATH); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/CastFunction.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/CastFunction.java index 8d75eee9c..98acf8fc9 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/CastFunction.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/CastFunction.java @@ -96,6 +96,12 @@ public ISequence execute(@NonNull IFunction function, return ISequence.of(castItem); } + /** + * A callback used to perform a casting operation. + * + * @param + * the Java type for the resulting item + */ @FunctionalInterface public interface ICastExecutor { /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java index c4eab2db9..d5b984abf 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/DefaultFunctionLibrary.java @@ -34,6 +34,7 @@ public class DefaultFunctionLibrary /** * Initialize the built-in function library. */ + @SuppressWarnings("deprecation") public DefaultFunctionLibrary() { // NOPMD - intentional // https://www.w3.org/TR/xpath-functions-31/#func-abs registerFunction(FnAbs.SIGNATURE); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntry.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntry.java index 6d0c41d9b..9500d8bb2 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntry.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/MapEntry.java @@ -29,7 +29,7 @@ public final class MapEntry { private static final String NAME = "entry"; @NonNull - public static final IFunction SIGNATURE = IFunction.builder() + static final IFunction SIGNATURE = IFunction.builder() .name(NAME) .namespace(MetapathConstants.NS_METAPATH_FUNCTIONS_MAP) .deterministic() diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/model/xml/ModuleLoader.java b/core/src/main/java/gov/nist/secauto/metaschema/core/model/xml/ModuleLoader.java index 8002f23c8..a7bb81362 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/model/xml/ModuleLoader.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/model/xml/ModuleLoader.java @@ -46,22 +46,23 @@ public class ModuleLoader @NonNull private final List modulePostProcessors; - /** - * Construct a new Metaschema loader. - */ - public ModuleLoader() { - this(CollectionUtil.emptyList()); - } - /** * Construct a new Metaschema loader, which applies the provided constraints to * loaded modules. * * @param constraints * a set of Metaschema module constraints + * @return the loader */ - public ModuleLoader(@NonNull Collection constraints) { - this(CollectionUtil.singletonList(new ExternalConstraintsModulePostProcessor(constraints))); + public ModuleLoader newInstanceUsingCoinstraints(@NonNull Collection constraints) { + return new ModuleLoader(CollectionUtil.singletonList(new ExternalConstraintsModulePostProcessor(constraints))); + } + + /** + * Construct a new Metaschema loader. + */ + public ModuleLoader() { + this(CollectionUtil.emptyList()); } /** From f7c0a9c9925890e028b20de771b787c2a7619220 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Thu, 14 Nov 2024 12:05:34 -0500 Subject: [PATCH 06/20] Addressed code review comments. --- .../core/MetaschemaJavaVersion.java | 3 + .../core/datatype/adapter/Base64Adapter.java | 19 ++++- .../datatype/adapter/DateTimeAdapter.java | 24 ++++-- .../datatype/adapter/HostnameAdapter.java | 2 +- .../flexmark/HtmlQuoteTagExtension.java | 2 +- .../flexmark/SuppressPTagExtension.java | 2 +- .../function/ComparisonFunctions.java | 2 +- .../metapath/function/library/FnMinMax.java | 39 +++++++--- .../metapath/item/atomic/IAnyAtomicItem.java | 4 +- .../metapath/item/atomic/IAnyUriItem.java | 11 ++- .../item/atomic/IBase64BinaryItem.java | 2 +- .../metapath/item/atomic/IBooleanItem.java | 4 +- .../core/metapath/item/atomic/IDateItem.java | 4 +- .../metapath/item/atomic/IDateTimeItem.java | 13 +++- .../item/atomic/IDayTimeDurationItem.java | 4 +- .../metapath/item/atomic/IDecimalItem.java | 4 +- .../metapath/item/atomic/IDurationItem.java | 16 +++- .../item/atomic/IEmailAddressItem.java | 4 +- .../metapath/item/atomic/IHostnameItem.java | 6 +- .../metapath/item/atomic/IIPAddressItem.java | 2 +- .../item/atomic/IIPv4AddressItem.java | 4 +- .../item/atomic/IIPv6AddressItem.java | 4 +- .../metapath/item/atomic/IIntegerItem.java | 2 +- .../metapath/item/atomic/IMarkupItem.java | 2 +- .../metapath/item/atomic/INcNameItem.java | 4 +- .../item/atomic/INonNegativeIntegerItem.java | 8 +- .../metapath/item/atomic/INumericItem.java | 74 +++++++++---------- .../item/atomic/IPositiveIntegerItem.java | 4 +- .../metapath/item/atomic/IStringItem.java | 4 +- .../metapath/item/atomic/ITemporalItem.java | 2 +- .../core/metapath/item/atomic/ITokenItem.java | 4 +- .../item/atomic/IUntypedAtomicItem.java | 2 +- .../item/atomic/IUriReferenceItem.java | 9 ++- .../core/metapath/item/atomic/IUuidItem.java | 8 +- .../item/atomic/IYearMonthDurationItem.java | 4 +- .../item/atomic/impl/AbstractStringItem.java | 9 +++ .../item/atomic/impl/UuidItemImpl.java | 2 +- .../function/library/FnCeilingTest.java | 5 +- 38 files changed, 201 insertions(+), 117 deletions(-) diff --git a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java index e19f020f2..249d760ce 100644 --- a/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java +++ b/core/src/main/java-templates/gov/nist/secauto/metaschema/core/MetaschemaJavaVersion.java @@ -5,6 +5,9 @@ /** * Provides version information for this library. + *

+ * This class exposes build-time metadata including version numbers, build + * timestamps, and Git repository information. */ public class MetaschemaJavaVersion implements IVersionInfo { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java index 6b5d8f4d1..8c4772744 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/Base64Adapter.java @@ -58,9 +58,10 @@ public ByteBuffer parse(String value) { @Override public ByteBuffer copy(Object obj) { ByteBuffer buffer = (ByteBuffer) obj; - final ByteBuffer clone - = buffer.isDirect() ? ByteBuffer.allocateDirect(buffer.capacity()) : ByteBuffer.allocate(buffer.capacity()); - final ByteBuffer readOnlyCopy = buffer.asReadOnlyBuffer(); + ByteBuffer clone = buffer.isDirect() + ? ByteBuffer.allocateDirect(buffer.capacity()) + : ByteBuffer.allocate(buffer.capacity()); + ByteBuffer readOnlyCopy = buffer.asReadOnlyBuffer(); readOnlyCopy.flip(); clone.put(readOnlyCopy); return clone; @@ -68,8 +69,18 @@ public ByteBuffer copy(Object obj) { @Override public String asString(Object value) { + ByteBuffer buffer = (ByteBuffer) value; + byte[] array; + if (buffer.hasArray()) { + array = buffer.array(); + } else { + // Handle direct buffers + array = new byte[buffer.remaining()]; + buffer.get(array); + } + Base64.Encoder encoder = Base64.getEncoder(); - return ObjectUtils.notNull(encoder.encodeToString(((ByteBuffer) value).array())); + return ObjectUtils.notNull(encoder.encodeToString(array)); } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java index 7e2dd7929..6d61a4e55 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapter.java @@ -55,15 +55,10 @@ public JsonFormatTypes getJsonRawType() { public AmbiguousDateTime parse(String value) { AmbiguousDateTime retval; try { - retval = new AmbiguousDateTime( - ObjectUtils.notNull(ZonedDateTime.from(DateFormats.DATE_TIME_WITH_TZ.parse(value))), - true); + retval = parseWithTimeZone(value); } catch (DateTimeParseException ex) { try { - LocalDateTime dateTime = LocalDateTime.from(DateFormats.DATE_TIME_WITHOUT_TZ.parse(value)); - retval = new AmbiguousDateTime( - ObjectUtils.notNull(ZonedDateTime.of(dateTime, ZoneOffset.UTC)), - false); + retval = parseWithoutTimeZone(value); } catch (DateTimeParseException ex2) { IllegalArgumentException newEx = new IllegalArgumentException(ex2.getLocalizedMessage(), ex2); newEx.addSuppressed(ex); @@ -73,6 +68,21 @@ public AmbiguousDateTime parse(String value) { return retval; } + @NonNull + private static AmbiguousDateTime parseWithTimeZone(@NonNull String value) { + return new AmbiguousDateTime( + ObjectUtils.notNull(ZonedDateTime.from(DateFormats.DATE_TIME_WITH_TZ.parse(value))), + true); + } + + @NonNull + private static AmbiguousDateTime parseWithoutTimeZone(@NonNull String value) { + LocalDateTime dateTime = LocalDateTime.from(DateFormats.DATE_TIME_WITHOUT_TZ.parse(value)); + return new AmbiguousDateTime( + ObjectUtils.notNull(ZonedDateTime.of(dateTime, ZoneOffset.UTC)), + false); + } + @Override public String asString(Object obj) { AmbiguousDateTime value = (AmbiguousDateTime) obj; diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java index 5014eac59..ab79caf20 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/adapter/HostnameAdapter.java @@ -37,7 +37,7 @@ public List getNames() { @Override public @NonNull - Class getItemClass() { + Class getItemClass() { return IHostnameItem.class; } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java index 563ec7278..1886c617c 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/HtmlQuoteTagExtension.java @@ -82,7 +82,7 @@ static class QTagNodeRenderer implements NodeRenderer { @Override public @Nullable - Set> getNodeRenderingHandlers() { + Set> getNodeRenderingHandlers() { return Collections.singleton( new NodeRenderingHandler<>(DoubleQuoteNode.class, this::render)); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java index 54cae7a3a..bbdd25bf1 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/SuppressPTagExtension.java @@ -51,7 +51,7 @@ static class PTagNodeRenderer implements NodeRenderer { @Override public @Nullable - Set> getNodeRenderingHandlers() { + Set> getNodeRenderingHandlers() { return Collections.singleton( new NodeRenderingHandler<>(Paragraph.class, this::render)); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java index 9c1854e7e..4d53bb5cc 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/ComparisonFunctions.java @@ -147,7 +147,7 @@ private static IAnyAtomicItem applyGeneralComparisonCast(@NonNull IAnyAtomicItem retval = IDecimalItem.cast(other); } else if (item instanceof IDayTimeDurationItem) { retval = IDayTimeDurationItem.cast(other); - } else if (item instanceof IDayTimeDurationItem) { + } else if (item instanceof IYearMonthDurationItem) { retval = IYearMonthDurationItem.cast(other); } else { retval = item.castAsType(other); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java index 7c871e279..5d5dc8a1e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnMinMax.java @@ -43,6 +43,11 @@ public final class FnMinMax { private static final String NAME_MIN = "min"; private static final String NAME_MAX = "max"; + /** + * Defines the set of primitive atomic item types supported by the min/max + * functions. This set is used for type validation and normalization during + * comparison operations. + */ @NonNull private static final Set> PRIMITIVE_ITEM_TYPES = ObjectUtils.notNull(Set.of( IStringItem.class, @@ -164,24 +169,40 @@ private static Stream normalize( return Stream.of(items.get(0)); } - List resultingItems = ObjectUtils.notNull(items.stream() + List resultingItems = convertUntypedItems(items); + Map, Integer> counts = countItemTypes(resultingItems); + return createNormalizedStream(resultingItems, counts); + } + + @NonNull + private static List convertUntypedItems( + @NonNull List items) { + return ObjectUtils.notNull(items.stream() .map(item -> item instanceof IUntypedAtomicItem ? IDecimalItem.cast(item) : item) .collect(Collectors.toList())); + } + + @NonNull + private static Map, Integer> countItemTypes( + @NonNull List items) { + return FunctionUtils.countTypes(PRIMITIVE_ITEM_TYPES, items); + } - Map, Integer> counts = FunctionUtils.countTypes( - PRIMITIVE_ITEM_TYPES, - resultingItems); + @NonNull + private static Stream createNormalizedStream( + @NonNull List items, + @NonNull Map, Integer> counts) { Stream stream = null; if (counts.size() == 1) { - stream = resultingItems.stream(); + stream = items.stream(); } else if (counts.size() > 1) { - int size = resultingItems.size(); + int size = items.size(); if (counts.getOrDefault(IStringItem.class, 0) + counts.getOrDefault(IAnyUriItem.class, 0) == size) { - stream = resultingItems.stream() + stream = items.stream() .map(IAnyAtomicItem::asStringItem); } else if (counts.getOrDefault(IDecimalItem.class, 0) == size) { - stream = resultingItems.stream() + stream = items.stream() .map(item -> (IDecimalItem) item); } } @@ -190,7 +211,7 @@ private static Stream normalize( throw new InvalidArgumentFunctionException( InvalidArgumentFunctionException.INVALID_ARGUMENT_TYPE, String.format("Values must all be of a single atomic type. Their types are '%s'.", - FunctionUtils.getTypes(resultingItems).stream() + FunctionUtils.getTypes(items).stream() .map(Class::getName) .collect(Collectors.joining(",")))); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java index 78bccead3..fef08f6fe 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyAtomicItem.java @@ -15,7 +15,9 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * The interface shares by all atomic items. + * The interface shared by all atomic items, representing indivisible data + * values that serve as the fundamental building blocks for complex data + * structures in the Metaschema framework. */ public interface IAnyAtomicItem extends IAtomicValuedItem, IPrintable { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java index 7208046ba..2521e5bdf 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IAnyUriItem.java @@ -16,7 +16,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a URI data value. + * An atomic Metapath item containing a URI data value. */ public interface IAnyUriItem extends IAnyAtomicItem { /** @@ -35,7 +35,7 @@ static IAnyUriItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid URI. %s", + String.format("Invalid URI value '%s'. %s", value, ex.getLocalizedMessage()), ex); @@ -44,6 +44,13 @@ static IAnyUriItem valueOf(@NonNull String value) { /** * Construct a new URI item using the provided URI {@code value}. + *

+ * Example usage: + * + *

+   * URI uri = URI.create("http://example.com");
+   * IAnyUriItem item = IAnyUriItem.valueOf(uri);
+   * 
* * @param value * a URI diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java index ad6603d5e..82a912079 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBase64BinaryItem.java @@ -15,7 +15,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a Base64 encoded data value. + * An atomic Metapath item containing a Base64 encoded data value. */ public interface IBase64BinaryItem extends IAnyAtomicItem { diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java index 9086e2056..20016c0ed 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IBooleanItem.java @@ -13,7 +13,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item with a boolean value. + * An atomic Metapath item with a boolean value. */ public interface IBooleanItem extends IAnyAtomicItem { /** @@ -50,7 +50,7 @@ static IBooleanItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid boolean value. %s", + String.format("Invalid boolean value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java index 5fb9bbc66..5f391ca1e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateItem.java @@ -19,7 +19,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a date data value. + * An atomic Metapath item containing a date data value. */ public interface IDateItem extends ITemporalItem { @@ -37,7 +37,7 @@ static IDateItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid date. %s", + String.format("Invalid date value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java index bf8b0290b..ab9f5765b 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDateTimeItem.java @@ -17,7 +17,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a date/time data value. + * An atomic Metapath item containing a date/time data value. */ public interface IDateTimeItem extends ITemporalItem { /** @@ -34,7 +34,7 @@ static IDateTimeItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid date/time. %s", + String.format("Invalid date/time value '%s'. %s", value, ex.getLocalizedMessage()), ex); @@ -43,10 +43,15 @@ static IDateTimeItem valueOf(@NonNull String value) { /** * Construct a new date/time item using the provided {@code value}. + *

+ * This method handles recording if an explicit timezone was provided using the + * {@link AmbiguousDateTime}. The {@link AmbiguousDateTime#hasTimeZone()} method + * can be called to determine if timezone information is present. * * @param value * a date/time, without time zone information * @return the new item + * @see AmbiguousDateTime for more details on timezone handling */ @NonNull static IDateTimeItem valueOf(@NonNull AmbiguousDateTime value) { @@ -55,6 +60,10 @@ static IDateTimeItem valueOf(@NonNull AmbiguousDateTime value) { /** * Construct a new date/time item using the provided {@code value}. + *

+ * This method handles dates with explicit timezone information using + * ZonedDateTime. The timezone is preserved as specified in the input and is + * significant for date/time operations and comparisons. * * @param value * a date/time, with time zone information diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java index cee41f074..42a28ecb2 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDayTimeDurationItem.java @@ -15,7 +15,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a duration data value in days, hours, and + * An atomic Metapath item containing a duration data value in days, hours, and * seconds. */ public interface IDayTimeDurationItem extends IDurationItem { @@ -37,7 +37,7 @@ static IDayTimeDurationItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid day/time duration. %s", + String.format("Invalid day/time value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java index 24eaf8a55..a6900b323 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDecimalItem.java @@ -17,7 +17,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a decimal data value. + * An atomic Metapath item containing a decimal data value. */ public interface IDecimalItem extends INumericItem { /** @@ -42,7 +42,7 @@ static IDecimalItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid decimal. %s", + String.format("Invalid decimal value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java index 7d318a8d3..6b0b7fc7d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IDurationItem.java @@ -12,7 +12,17 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item representing a duration data value. + * An atomic Metapath item representing a duration data value. + *

+ * This interface supports both day-time and year-month duration formats + * following the ISO 8601 standard. Examples of valid durations include: + *

+ * + * @see IDayTimeDurationItem + * @see IYearMonthDurationItem */ public interface IDurationItem extends IAnyAtomicItem { /** @@ -45,7 +55,9 @@ static IDurationItem cast(@NonNull IAnyAtomicItem item) { try { retval = IYearMonthDurationItem.valueOf(value); } catch (IllegalStateException ex2) { - InvalidValueForCastFunctionException newEx = new InvalidValueForCastFunctionException(ex2); + InvalidValueForCastFunctionException newEx = new InvalidValueForCastFunctionException( + String.format("Value '%s' cannot be parsed as either a day-time or year-month duration", value), + ex2); newEx.addSuppressed(ex); throw newEx; // NOPMD context as suppressed } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java index 400a0b339..bc54171fc 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IEmailAddressItem.java @@ -13,7 +13,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing an email address data value. + * An atomic Metapath item containing an email address data value. */ public interface IEmailAddressItem extends IStringItem { /** @@ -32,7 +32,7 @@ static IEmailAddressItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid email address. %s", + String.format("Invalid email address value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java index 6257b6400..001f1bfc4 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IHostnameItem.java @@ -13,14 +13,14 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a hostname data value. + * An atomic Metapath item containing a hostname data value. */ public interface IHostnameItem extends IStringItem { /** * Construct a new host name item using the provided string {@code value}. * * @param value - * a string representing an host name value + * a string representing a host name value * @return the new item */ @NonNull @@ -30,7 +30,7 @@ static IHostnameItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid hostname. %s", + String.format("Invalid hostname value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java index 852c169d1..0fafb2810 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPAddressItem.java @@ -11,7 +11,7 @@ import inet.ipaddr.IPAddress; /** - * A Metapath atomic item representing an IP address data value. + * An atomic Metapath item representing an IP address data value. */ public interface IIPAddressItem extends IUntypedAtomicItem { /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java index 33e0d5668..7de02e6f5 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv4AddressItem.java @@ -14,7 +14,7 @@ import inet.ipaddr.ipv4.IPv4Address; /** - * A Metapath atomic item containing an IPv4 address data value. + * An atomic Metapath item containing an IPv4 address data value. */ public interface IIPv4AddressItem extends IIPAddressItem { @@ -32,7 +32,7 @@ static IIPv4AddressItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid IPv4 address. %s", + String.format("Invalid IPv4 address value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java index c3c9b2a46..82c3234a8 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIPv6AddressItem.java @@ -14,7 +14,7 @@ import inet.ipaddr.ipv6.IPv6Address; /** - * A Metapath atomic item containing an IPv4 address data value. + * An atomic Metapath item containing an IPv6 address data value. */ public interface IIPv6AddressItem extends IIPAddressItem { @@ -32,7 +32,7 @@ static IIPv6AddressItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid IPv6 address. %s", + String.format("Invalid IPv6 address value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java index f40ba46b8..8190df2eb 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IIntegerItem.java @@ -15,7 +15,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing an integer data value. + * An atomic Metapath item containing an integer data value. */ public interface IIntegerItem extends IDecimalItem { /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java index 7d657cf39..5e27c6675 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IMarkupItem.java @@ -17,7 +17,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item representing a Markup data value. + * An atomic Metapath item representing a Markup data value. */ public interface IMarkupItem extends IUntypedAtomicItem { /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java index 05a5a9470..3253d8d2d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INcNameItem.java @@ -13,7 +13,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a non-colonized name data value. + * An atomic Metapath item containing a non-colonized name (NCName) data value. */ @Deprecated(forRemoval = true, since = "0.7.0") public interface INcNameItem extends IStringItem { @@ -32,7 +32,7 @@ static INcNameItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid non-colonized name. %s", + String.format("Invalid non-colonized name value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java index b3dc83a59..d24dcdc16 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INonNegativeIntegerItem.java @@ -16,7 +16,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a non-negative integer data value. + * An atomic Metapath item containing a non-negative integer data value. */ public interface INonNegativeIntegerItem extends IIntegerItem { /** @@ -42,11 +42,11 @@ public interface INonNegativeIntegerItem extends IIntegerItem { @NonNull static INonNegativeIntegerItem valueOf(@NonNull String value) { try { - return new NonNegativeIntegerItemImpl(MetaschemaDataTypeProvider.NON_NEGATIVE_INTEGER.parse(value)); + return valueOf(MetaschemaDataTypeProvider.NON_NEGATIVE_INTEGER.parse(value)); } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid non-negative integer. %s", + String.format("Invalid non-negative integer value '%s'. %s", value, ex.getLocalizedMessage()), ex); @@ -96,7 +96,7 @@ static INonNegativeIntegerItem valueOf(@NonNull BigInteger value) { if (value.compareTo(BigInteger.ZERO) < 0) { throw new InvalidTypeMetapathException( null, - String.format("Integer value '%s' is negative.", value)); + String.format("Integer value '%s' must not be negative.", value)); } return new NonNegativeIntegerItemImpl(value); } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java index 9762510e3..99542b9dc 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/INumericItem.java @@ -19,7 +19,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a numeric data value. + * An atomic Metapath item containing a numeric data value. */ public interface INumericItem extends IAnyAtomicItem { @@ -120,7 +120,6 @@ default INumericItem round() { * (negative value} or after (positive value) the decimal point. * @return the rounded value */ - @SuppressWarnings("PMD.CognitiveComplexity") // ok @NonNull default INumericItem round(@NonNull IIntegerItem precisionItem) { int precision; @@ -130,45 +129,38 @@ default INumericItem round(@NonNull IIntegerItem precisionItem) { throw new ArithmeticFunctionException(ArithmeticFunctionException.OVERFLOW_UNDERFLOW_ERROR, "Numeric operation overflow/underflow.", ex); } - INumericItem retval; - if (precision >= 0) { - // round to precision decimal places - if (this instanceof IIntegerItem) { - retval = this; - } else { - // IDecimalItem - BigDecimal value = asDecimal(); - if (value.signum() == -1) { - retval = IDecimalItem.valueOf( - ObjectUtils.notNull( - value.round(new MathContext(precision + value.precision() - value.scale(), RoundingMode.HALF_DOWN)))); - } else { - retval = IDecimalItem.valueOf( - ObjectUtils.notNull( - value.round(new MathContext(precision + value.precision() - value.scale(), RoundingMode.HALF_UP)))); - } - - // cast result to original type - retval = castAsType(retval); - } - } else { - // round to a power of 10 - BigInteger value = asInteger(); - BigInteger divisor = BigInteger.TEN.pow(0 - precision); - - @NonNull - BigInteger result; - if (divisor.compareTo(value.abs()) > 0) { - result = ObjectUtils.notNull(BigInteger.ZERO); - } else { - BigInteger remainder = value.mod(divisor); - BigInteger lessRemainder = value.subtract(remainder); - BigInteger halfDivisor = divisor.divide(BigInteger.TWO); - result = ObjectUtils.notNull( - remainder.compareTo(halfDivisor) >= 0 ? lessRemainder.add(divisor) : lessRemainder); - } - retval = IIntegerItem.valueOf(result); + return precision >= 0 + ? roundWithPositivePrecision(precision) + : roundWithNegativePrecision(precision); + } + + @SuppressWarnings("PMD.OnlyOneReturn") + @NonNull + private INumericItem roundWithPositivePrecision(int precision) { + if (this instanceof IIntegerItem) { + return this; + } + BigDecimal value = asDecimal(); + BigDecimal rounded = value.signum() == -1 + ? value.round(new MathContext(precision + value.precision() - value.scale(), RoundingMode.HALF_DOWN)) + : value.round(new MathContext(precision + value.precision() - value.scale(), RoundingMode.HALF_UP)); + return castAsType(IDecimalItem.valueOf(ObjectUtils.notNull(rounded))); + } + + @SuppressWarnings("PMD.OnlyOneReturn") + @NonNull + private INumericItem roundWithNegativePrecision(int precision) { + BigInteger value = asInteger(); + BigInteger divisor = BigInteger.TEN.pow(0 - precision); + if (divisor.compareTo(value.abs()) > 0) { + return IIntegerItem.ZERO; } - return retval; + BigInteger remainder = value.mod(divisor); + BigInteger lessRemainder = value.subtract(remainder); + BigInteger halfDivisor = divisor.divide(BigInteger.TWO); + BigInteger result = remainder.compareTo(halfDivisor) >= 0 + ? lessRemainder.add(divisor) + : lessRemainder; + return IIntegerItem.valueOf(ObjectUtils.notNull(result)); } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java index 009b050db..51014d7f0 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IPositiveIntegerItem.java @@ -14,7 +14,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a positive integer data value. + * An atomic Metapath item containing a positive integer data value. */ public interface IPositiveIntegerItem extends INonNegativeIntegerItem { /** @@ -40,7 +40,7 @@ static IPositiveIntegerItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid positive integer. %s", + String.format("Invalid positive integer value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java index e4e31a2bd..1c9c7d31a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IStringItem.java @@ -13,7 +13,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a text data value. + * An atomic Metapath item containing a text data value. */ public interface IStringItem extends IAnyAtomicItem { /** @@ -30,7 +30,7 @@ static IStringItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid IPv4 address. %s", + String.format("Invalid string value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java index fb92e5d79..f60a6e16a 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITemporalItem.java @@ -10,7 +10,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a temporal data value. + * An atomic Metapath item containing a temporal data value. */ public interface ITemporalItem extends IAnyAtomicItem { /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java index 56ab75625..9dacff82e 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/ITokenItem.java @@ -13,7 +13,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a text token data value. + * An atomic Metapath item containing a text token data value. */ public interface ITokenItem extends IStringItem { /** @@ -32,7 +32,7 @@ static ITokenItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid token. %s", + String.format("Invalid token value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java index 555b2c7de..af125d870 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUntypedAtomicItem.java @@ -6,7 +6,7 @@ package gov.nist.secauto.metaschema.core.metapath.item.atomic; /** - * A Metapath atomic item containing an untyped atomic data value. + * An atomic Metapath item containing an untyped atomic data value. */ public interface IUntypedAtomicItem extends IAnyAtomicItem { // this interface has no additional methods diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java index 337b36a2d..ef17d7001 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUriReferenceItem.java @@ -15,7 +15,12 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a URI reference data value. + * An atomic Metapath item containing a URI reference data value that complies + * with RFC2396. URI references can be absolute URIs, relative URIs, or + * same-document references. + * + * @see java.net.URI + * @see RFC2396 */ public interface IUriReferenceItem extends IAnyUriItem { /** @@ -34,7 +39,7 @@ static IUriReferenceItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid URI reference. %s", + String.format("Invalid URI reference value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java index b3b11a035..134a84d69 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IUuidItem.java @@ -15,14 +15,14 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a UUID data value. + * An atomic Metapath item containing a UUID data value. */ public interface IUuidItem extends IStringItem { /** - * Construct a new URI item using the provided string {@code value}. + * Construct a new UUID item using the provided string {@code value}. * * @param value - * a string representing a URI + * a string representing a UUID * @return the new item * @throws InvalidTypeMetapathException * if the given string violates RFC4122 @@ -34,7 +34,7 @@ static IUuidItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid UUID. %s", + String.format("Invalid UUID value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java index db2fcea69..3cffc2934 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/IYearMonthDurationItem.java @@ -16,7 +16,7 @@ import edu.umd.cs.findbugs.annotations.NonNull; /** - * A Metapath atomic item containing a duration data value in years and months. + * An atomic Metapath item containing a duration data value in years and months. */ public interface IYearMonthDurationItem extends IDurationItem { /** @@ -38,7 +38,7 @@ static IYearMonthDurationItem valueOf(@NonNull String value) { } catch (IllegalArgumentException ex) { throw new InvalidTypeMetapathException( null, - String.format("The value '%s' is not a valid year/month duration. %s", + String.format("Invalid year/month duration value '%s'. %s", value, ex.getLocalizedMessage()), ex); diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java index 486da4d03..a4e61b21d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/AbstractStringItem.java @@ -21,8 +21,17 @@ public abstract class AbstractStringItem extends AbstractAnyAtomicItem implements IStringItem { private static final String WHITESPACE_SEGMENT = "[ \t\r\n]"; + /** + * Pattern to match one or more whitespace characters at the end of a string. + */ private static final Pattern TRIM_END = Pattern.compile(WHITESPACE_SEGMENT + "++$"); + /** + * Pattern to match one or more whitespace characters at the start of a string. + */ private static final Pattern TRIM_START = Pattern.compile("^" + WHITESPACE_SEGMENT + "+"); + /** + * Pattern to match two or more consecutive whitespace characters. + */ private static final Pattern TRIM_MIDDLE = Pattern.compile(WHITESPACE_SEGMENT + "{2,}"); /** diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java index ef3c3bdde..94c914961 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/item/atomic/impl/UuidItemImpl.java @@ -80,7 +80,7 @@ public IUuidItem getKey() { @Override public int hashCode() { - return getKey().hashCode(); + return getKey().asUuid().hashCode(); } @Override diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java index 306c421dc..c2ea37004 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/metapath/function/library/FnCeilingTest.java @@ -27,7 +27,10 @@ class FnCeilingTest private static Stream provideValues() { return Stream.of( Arguments.of(integer(11), decimal("10.5")), - Arguments.of(integer(-10), decimal("-10.5"))); + Arguments.of(integer(-10), decimal("-10.5")), + Arguments.of(integer(11), decimal("10.1")), + Arguments.of(integer(0), decimal("0.0")), + Arguments.of(integer(1), decimal("0.999999"))); } @ParameterizedTest From 9a4237f9c456a562c02665f12bffe3d58c50d287 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Thu, 14 Nov 2024 14:04:10 -0500 Subject: [PATCH 07/20] Improved date and dateTime adapter unit testing to check for ambiguity and resulting time value. --- .../datatype/adapter/DateAdapterTest.java | 30 ++++++- .../datatype/adapter/DateTimeAdapterTest.java | 80 +++++++++++++++---- 2 files changed, 90 insertions(+), 20 deletions(-) diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapterTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapterTest.java index 354b989be..c2d483241 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapterTest.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateAdapterTest.java @@ -5,17 +5,39 @@ package gov.nist.secauto.metaschema.core.datatype.adapter; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDate; + import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.stream.Stream; import edu.umd.cs.findbugs.annotations.NonNull; class DateAdapterTest { private static final DateAdapter ADAPTER = new DateAdapter(); + private static Stream provideValues() { + return Stream.of( + Arguments.of("2018-01-01", true, ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)), + Arguments.of("2020-06-23Z", false, ZonedDateTime.of(2020, 6, 23, 0, 0, 0, 0, ZoneOffset.UTC)), + Arguments.of("2020-06-23-04:00", false, ZonedDateTime.of(2020, 6, 23, 0, 0, 0, 0, ZoneOffset.of("-04:00"))), + Arguments.of("2020-01-01", true, ZonedDateTime.of(2020, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)), + Arguments.of("2018-01-01", true, ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC))); + } + @ParameterizedTest - @ValueSource(strings = { "2018-01-01", "2020-06-23Z", "2020-06-23-04:00", "2020-06-23", "2020-01-01" }) - void testSimpleDate(@NonNull String date) { - ADAPTER.parse(date); + @MethodSource("provideValues") + void testSimpleDate(@NonNull String actual, boolean ambiguous, @NonNull ZonedDateTime expected) { + AmbiguousDate date = ADAPTER.parse(actual); + assertAll( + () -> assertEquals(ambiguous, !date.hasTimeZone()), + () -> assertEquals(expected, date.getValue())); } } diff --git a/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapterTest.java b/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapterTest.java index a98c5a93a..90074aaa9 100644 --- a/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapterTest.java +++ b/core/src/test/java/gov/nist/secauto/metaschema/core/datatype/adapter/DateTimeAdapterTest.java @@ -5,27 +5,75 @@ package gov.nist.secauto.metaschema.core.datatype.adapter; -import gov.nist.secauto.metaschema.core.util.ObjectUtils; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +import gov.nist.secauto.metaschema.core.datatype.object.AmbiguousDateTime; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; + +import edu.umd.cs.findbugs.annotations.NonNull; class DateTimeAdapterTest { + private static final DateTimeAdapter ADAPTER = new DateTimeAdapter(); - @ParameterizedTest - @ValueSource(strings = { - "2018-01-01T00:00:00", - "2019-09-28T23:20:50.52Z", - "2019-09-28T23:20:50.0Z", - "2019-09-28T23:20:50.5200", - "2019-12-02T16:39:57-08:00", - "2019-12-02T16:39:57.100-08:00", - "2019-12-02T16:39:57", - "2019-12-31T23:59:59Z", - "2019-12-31T23:59:59" - }) - void testSimpleDate(String date) { - new DateTimeAdapter().parse(ObjectUtils.requireNonNull(date)); + private static Stream provideValues() { + return Stream.of( + Arguments.of( + "2018-01-01T00:00:00", + true, + ZonedDateTime.of(2018, 1, 1, 0, 0, 0, 0, ZoneOffset.UTC)), + Arguments.of( + "2019-09-28T23:20:50.52Z", + false, + ZonedDateTime.of(2019, 9, 28, 23, 20, 50, toNanos(0.52), ZoneOffset.UTC)), + Arguments.of( + "2019-09-28T23:20:50.0Z", + false, + ZonedDateTime.of(2019, 9, 28, 23, 20, 50, 0, ZoneOffset.UTC)), + Arguments.of( + "2019-09-28T23:20:50.5200", + true, + ZonedDateTime.of(2019, 9, 28, 23, 20, 50, toNanos(0.5200), ZoneOffset.UTC)), + Arguments.of( + "2019-12-02T16:39:57-08:00", + false, + ZonedDateTime.of(2019, 12, 2, 16, 39, 57, 0, ZoneOffset.of("-08:00"))), + Arguments.of( + "2019-12-02T16:39:57.100-08:00", + false, + ZonedDateTime.of(2019, 12, 2, 16, 39, 57, toNanos(0.100), ZoneOffset.of("-08:00"))), + Arguments.of( + "2019-12-02T16:39:57", + true, + ZonedDateTime.of(2019, 12, 2, 16, 39, 57, 0, ZoneOffset.UTC)), + Arguments.of( + "2019-12-31T23:59:59Z", + false, + ZonedDateTime.of(2019, 12, 31, 23, 59, 59, 0, ZoneOffset.UTC)), + Arguments.of( + "2019-12-31T23:59:59", + true, + ZonedDateTime.of(2019, 12, 31, 23, 59, 59, 0, ZoneOffset.UTC))); } + private static int toNanos(double fraction) { + return (int) Math.round(TimeUnit.SECONDS.toNanos(1) * fraction); + } + + @ParameterizedTest + @MethodSource("provideValues") + void testSimpleDateTime(@NonNull String actual, boolean ambiguous, @NonNull ZonedDateTime expected) { + AmbiguousDateTime date = ADAPTER.parse(actual); + assertAll( + () -> assertEquals(ambiguous, !date.hasTimeZone()), + () -> assertEquals(expected, date.getValue())); + } } From 1b2312f82eca64ae6fd5837521a87f2e1d86994a Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Thu, 14 Nov 2024 18:18:15 -0500 Subject: [PATCH 08/20] Code formatting. --- .../metapath/antlr/AbstractAstVisitor.java | 60 +++++++++++-------- .../metapath/antlr/FailingErrorListener.java | 7 +++ .../metapath/antlr/Metapath10ParserBase.java | 35 ++++++----- .../core/metapath/antlr/ParseTreePrinter.java | 4 ++ 4 files changed, 64 insertions(+), 42 deletions(-) diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/AbstractAstVisitor.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/AbstractAstVisitor.java index 1b682f269..93d899ca0 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/AbstractAstVisitor.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/AbstractAstVisitor.java @@ -79,7 +79,15 @@ import edu.umd.cs.findbugs.annotations.NonNull; -public abstract class AbstractAstVisitor // NOPMD +/** + * This abstract class supports processing an ANTLR-based abstract syntax tree + * by walking the tree using a visitor pattern. + * + * @param + * the Java type of the result produced through visitation + */ +@SuppressWarnings({ "PMD.ExcessivePublicCount", "PMD.CyclomaticComplexity" }) +public abstract class AbstractAstVisitor extends Metapath10BaseVisitor { /** @@ -150,7 +158,7 @@ public R visitMetapath(MetapathContext ctx) { @Override public R visitExpr(ExprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleExpr(ctx)); + return handle(ctx, context -> handleExpr(ctx)); } @Override @@ -185,7 +193,7 @@ public R visitPrimaryexpr(PrimaryexprContext ctx) { @Override public R visitLiteral(LiteralContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleStringLiteral(ctx)); + return handle(ctx, context -> handleStringLiteral(ctx)); } /** @@ -200,7 +208,7 @@ public R visitLiteral(LiteralContext ctx) { @Override public R visitNumericliteral(NumericliteralContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleNumericLiteral(ctx)); + return handle(ctx, context -> handleNumericLiteral(ctx)); } // ================================================================== @@ -266,7 +274,7 @@ public R visitParenthesizedexpr(ParenthesizedexprContext ctx) { @Override public R visitContextitemexpr(ContextitemexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleContextitemexpr(ctx)); + return handle(ctx, context -> handleContextitemexpr(ctx)); } // ========================================================================= @@ -285,7 +293,7 @@ public R visitContextitemexpr(ContextitemexprContext ctx) { @Override public R visitFunctioncall(FunctioncallContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleFunctioncall(ctx)); + return handle(ctx, context -> handleFunctioncall(ctx)); } @Override @@ -326,7 +334,7 @@ public R visitEnclosedexpr(EnclosedexprContext ctx) { @Override public R visitPostfixexpr(PostfixexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handlePostfixexpr(ctx)); + return handle(ctx, context -> handlePostfixexpr(ctx)); } /** @@ -375,7 +383,7 @@ public R visitLookup(LookupContext ctx) { @Override public R visitPathexpr(PathexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handlePathexpr(ctx)); + return handle(ctx, context -> handlePathexpr(ctx)); } // ============================================================ @@ -395,7 +403,7 @@ public R visitPathexpr(PathexprContext ctx) { @Override public R visitRelativepathexpr(RelativepathexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleRelativepathexpr(ctx)); + return handle(ctx, context -> handleRelativepathexpr(ctx)); } // ================================================ @@ -421,7 +429,7 @@ public R visitStepexpr(StepexprContext ctx) { public R visitForwardstep(ForwardstepContext ctx) { assert ctx != null; // this will either call the handler or forward for AbbrevforwardstepContext - return handle(ctx, (context) -> handleForwardstep(ctx)); + return handle(ctx, context -> handleForwardstep(ctx)); } /** @@ -437,7 +445,7 @@ public R visitForwardstep(ForwardstepContext ctx) { public R visitReversestep(ReversestepContext ctx) { assert ctx != null; // this will either call the handler or forward for AbbrevreversestepContext - return handle(ctx, (context) -> handleReversestep(ctx)); + return handle(ctx, context -> handleReversestep(ctx)); } // ====================================================================== @@ -456,7 +464,7 @@ public R visitReversestep(ReversestepContext ctx) { @Override public R visitAxisstep(AxisstepContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleAxisstep(ctx)); + return handle(ctx, context -> handleAxisstep(ctx)); } @Override @@ -569,7 +577,7 @@ public R visitAbbrevreversestep(AbbrevreversestepContext ctx) { @Override public R visitRangeexpr(RangeexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleRangeexpr(ctx)); + return handle(ctx, context -> handleRangeexpr(ctx)); } // ======================================================================== @@ -588,7 +596,7 @@ public R visitRangeexpr(RangeexprContext ctx) { @Override public R visitUnionexpr(UnionexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleUnionexpr(ctx)); + return handle(ctx, context -> handleUnionexpr(ctx)); } /** @@ -603,7 +611,7 @@ public R visitUnionexpr(UnionexprContext ctx) { @Override public R visitIntersectexceptexpr(IntersectexceptexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleIntersectexceptexpr(ctx)); + return handle(ctx, context -> handleIntersectexceptexpr(ctx)); } // ====================================================================== @@ -622,7 +630,7 @@ public R visitIntersectexceptexpr(IntersectexceptexprContext ctx) { @Override public R visitAdditiveexpr(AdditiveexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleAdditiveexpr(ctx)); + return handle(ctx, context -> handleAdditiveexpr(ctx)); } /** @@ -637,7 +645,7 @@ public R visitAdditiveexpr(AdditiveexprContext ctx) { @Override public R visitMultiplicativeexpr(MultiplicativeexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleMultiplicativeexpr(ctx)); + return handle(ctx, context -> handleMultiplicativeexpr(ctx)); } /** @@ -652,7 +660,7 @@ public R visitMultiplicativeexpr(MultiplicativeexprContext ctx) { @Override public R visitUnaryexpr(UnaryexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleUnaryexpr(ctx)); + return handle(ctx, context -> handleUnaryexpr(ctx)); } @Override @@ -678,7 +686,7 @@ public R visitValueexpr(ValueexprContext ctx) { @Override public R visitStringconcatexpr(StringconcatexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleStringconcatexpr(ctx)); + return handle(ctx, context -> handleStringconcatexpr(ctx)); } // ======================================================================= @@ -697,7 +705,7 @@ public R visitStringconcatexpr(StringconcatexprContext ctx) { @Override public R visitComparisonexpr(ComparisonexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleComparisonexpr(ctx)); + return handle(ctx, context -> handleComparisonexpr(ctx)); } @Override @@ -728,7 +736,7 @@ public R visitGeneralcomp(GeneralcompContext ctx) { @Override public R visitOrexpr(OrexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleOrexpr(ctx)); + return handle(ctx, context -> handleOrexpr(ctx)); } /** @@ -743,7 +751,7 @@ public R visitOrexpr(OrexprContext ctx) { @Override public R visitAndexpr(AndexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleAndexpr(ctx)); + return handle(ctx, context -> handleAndexpr(ctx)); } // ==================================================================== @@ -762,7 +770,7 @@ public R visitAndexpr(AndexprContext ctx) { @Override public R visitForexpr(ForexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleForexpr(ctx)); + return handle(ctx, context -> handleForexpr(ctx)); } @Override @@ -922,7 +930,7 @@ public R visitUnarylookup(UnarylookupContext ctx) { @Override public R visitIfexpr(IfexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleIfexpr(ctx)); + return handle(ctx, context -> handleIfexpr(ctx)); } /* @@ -966,7 +974,7 @@ public R visitQuantifiedexpr(QuantifiedexprContext ctx) { @Override public R visitSimplemapexpr(SimplemapexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleSimplemapexpr(ctx)); + return handle(ctx, context -> handleSimplemapexpr(ctx)); } /* @@ -987,7 +995,7 @@ public R visitSimplemapexpr(SimplemapexprContext ctx) { @Override public R visitArrowexpr(ArrowexprContext ctx) { assert ctx != null; - return handle(ctx, (context) -> handleArrowexpr(ctx)); + return handle(ctx, context -> handleArrowexpr(ctx)); } @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/FailingErrorListener.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/FailingErrorListener.java index aea605851..94dcb57c4 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/FailingErrorListener.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/FailingErrorListener.java @@ -10,6 +10,13 @@ import org.antlr.v4.runtime.Recognizer; import org.antlr.v4.runtime.misc.ParseCancellationException; +/** + * An ANTLR error listener that throws a {@link ParseCancellationException} when + * a syntax error is found. + *

+ * The exception message contains details around the line and character position + * where the error occurred. + */ public class FailingErrorListener extends BaseErrorListener { @Override diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/Metapath10ParserBase.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/Metapath10ParserBase.java index 44f8661d6..8347b132d 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/Metapath10ParserBase.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/Metapath10ParserBase.java @@ -8,6 +8,9 @@ import org.antlr.v4.runtime.Parser; import org.antlr.v4.runtime.TokenStream; +/** + * The base class for Metapath ANTLR processing. + */ public abstract class Metapath10ParserBase extends Parser { /** @@ -27,21 +30,21 @@ protected Metapath10ParserBase(TokenStream input) { * {@code false} otherwise */ protected boolean isFuncCall() { - return !(getInputStream().LA(1) == Metapath10.KW_ARRAY - || getInputStream().LA(1) == Metapath10.KW_FLAG - || getInputStream().LA(1) == Metapath10.KW_COMMENT - || getInputStream().LA(1) == Metapath10.KW_DOCUMENT_NODE - || getInputStream().LA(1) == Metapath10.KW_ELEMENT - || getInputStream().LA(1) == Metapath10.KW_EMPTY_SEQUENCE - || getInputStream().LA(1) == Metapath10.KW_FUNCTION - || getInputStream().LA(1) == Metapath10.KW_IF - || getInputStream().LA(1) == Metapath10.KW_ITEM - || getInputStream().LA(1) == Metapath10.KW_MAP - || getInputStream().LA(1) == Metapath10.KW_NAMESPACE_NODE - || getInputStream().LA(1) == Metapath10.KW_NODE - || getInputStream().LA(1) == Metapath10.KW_PROCESSING_INSTRUCTION - || getInputStream().LA(1) == Metapath10.KW_SCHEMA_ATTRIBUTE - || getInputStream().LA(1) == Metapath10.KW_SCHEMA_ELEMENT - || getInputStream().LA(1) == Metapath10.KW_TEXT); + return getInputStream().LA(1) != Metapath10.KW_ARRAY + && getInputStream().LA(1) != Metapath10.KW_FLAG + && getInputStream().LA(1) != Metapath10.KW_COMMENT + && getInputStream().LA(1) != Metapath10.KW_DOCUMENT_NODE + && getInputStream().LA(1) != Metapath10.KW_ELEMENT + && getInputStream().LA(1) != Metapath10.KW_EMPTY_SEQUENCE + && getInputStream().LA(1) != Metapath10.KW_FUNCTION + && getInputStream().LA(1) != Metapath10.KW_IF + && getInputStream().LA(1) != Metapath10.KW_ITEM + && getInputStream().LA(1) != Metapath10.KW_MAP + && getInputStream().LA(1) != Metapath10.KW_NAMESPACE_NODE + && getInputStream().LA(1) != Metapath10.KW_NODE + && getInputStream().LA(1) != Metapath10.KW_PROCESSING_INSTRUCTION + && getInputStream().LA(1) != Metapath10.KW_SCHEMA_ATTRIBUTE + && getInputStream().LA(1) != Metapath10.KW_SCHEMA_ELEMENT + && getInputStream().LA(1) != Metapath10.KW_TEXT; } } diff --git a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/ParseTreePrinter.java b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/ParseTreePrinter.java index b70e28cec..1cf327c21 100644 --- a/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/ParseTreePrinter.java +++ b/core/src/main/java/gov/nist/secauto/metaschema/core/metapath/antlr/ParseTreePrinter.java @@ -14,6 +14,10 @@ import edu.umd.cs.findbugs.annotations.NonNull; +/** + * Supports walking an ANTLR parse tree to generate a textual representation of + * the tree. + */ public class ParseTreePrinter { @SuppressWarnings("resource") @NotOwning From f727af52bb81c7495a64f013d6690b9d277dfa82 Mon Sep 17 00:00:00 2001 From: David Waltermire Date: Fri, 15 Nov 2024 12:38:25 -0500 Subject: [PATCH 09/20] Added a bunch of Javadocs. Performed some light refactoring. --- .../cli/processor/ProcessorVersion.java | 57 ++++ .../metaschema/cli/processor/Version.java | 40 --- .../cli/processor/AbstractExitStatus.java | 44 ++- .../cli/processor/CLIProcessor.java | 317 ++++++++++++------ .../metaschema/cli/processor/ExitCode.java | 3 + .../metaschema/cli/processor/ExitStatus.java | 9 + .../processor/InvalidArgumentException.java | 4 + .../cli/processor/MessageExitStatus.java | 14 +- .../cli/processor/NonMessageExitStatus.java | 3 + .../metaschema/cli/processor/OptionUtils.java | 10 + .../metaschema/cli/processor/VersionInfo.java | 23 -- .../command/AbstractCommandExecutor.java | 29 +- .../command/AbstractParentCommand.java | 29 +- .../command/AbstractTerminalCommand.java | 49 ++- .../cli/processor/command/CommandService.java | 22 +- .../command/DefaultExtraArgument.java | 45 --- .../cli/processor/command/ExtraArgument.java | 40 ++- .../cli/processor/command/ICommand.java | 132 +++++++- .../processor/command/ICommandExecutor.java | 35 ++ .../command/impl/DefaultExtraArgument.java | 41 +++ .../core/datatype/adapter/UuidAdapter.java | 7 +- .../datatype/markup/AbstractMarkupString.java | 12 +- .../core/datatype/markup/MarkupLine.java | 4 +- .../datatype/markup/MarkupLineAdapter.java | 1 - .../markup/MarkupMultilineAdapter.java | 1 - .../{flexmark => }/XmlMarkupParser.java | 4 +- .../markup/flexmark/FlexmarkFactory.java | 3 + .../flexmark/impl/AbstractMarkupWriter.java | 1 - .../{ => impl}/AstCollectingVisitor.java | 2 +- .../FixedEmphasisDelimiterProcessor.java | 2 +- .../{ => impl}/FlexmarkConfiguration.java | 4 +- .../{ => impl}/HtmlCodeRenderExtension.java | 2 +- .../flexmark/{ => impl}/IMarkupVisitor.java | 2 +- .../flexmark/{ => impl}/IMarkupWriter.java | 2 +- .../flexmark/{ => impl}/MarkupVisitor.java | 2 +- .../{ => impl}/MarkupXmlEventWriter.java | 3 +- .../{ => impl}/MarkupXmlStreamWriter.java | 4 +- .../{ => impl}/SuppressPTagExtension.java | 2 +- .../model/xml/impl/XmlbeansMarkupWriter.java | 6 +- .../markup/CommonmarkConformanceTest.java | 1 - .../datatype/markup/MarkupStringTest.java | 2 +- .../markup/flexmark/MarkupParserTest.java | 2 + .../commands/AbstractConvertSubcommand.java | 5 +- .../AbstractValidateContentCommand.java | 3 +- .../cli/commands/GenerateDiagramCommand.java | 5 +- .../cli/commands/GenerateSchemaCommand.java | 5 +- .../commands/metapath/MetapathCommand.java | 1 - .../model/testing/AbstractTestSuite.java | 88 ++--- .../xml/xmlbeans/handler/FormatType.java | 3 + .../handler/GenerationResultType.java | 4 + .../handler/ValidationResultType.java | 5 + 51 files changed, 770 insertions(+), 364 deletions(-) create mode 100644 cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/ProcessorVersion.java delete mode 100644 cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/Version.java delete mode 100644 cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/VersionInfo.java delete mode 100644 cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/command/DefaultExtraArgument.java create mode 100644 cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/command/impl/DefaultExtraArgument.java rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/{flexmark => }/XmlMarkupParser.java (97%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/AstCollectingVisitor.java (99%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/FixedEmphasisDelimiterProcessor.java (99%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/FlexmarkConfiguration.java (97%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/HtmlCodeRenderExtension.java (99%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/IMarkupVisitor.java (99%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/IMarkupWriter.java (99%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/MarkupVisitor.java (99%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/MarkupXmlEventWriter.java (97%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/MarkupXmlStreamWriter.java (96%) rename core/src/main/java/gov/nist/secauto/metaschema/core/datatype/markup/flexmark/{ => impl}/SuppressPTagExtension.java (99%) diff --git a/cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/ProcessorVersion.java b/cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/ProcessorVersion.java new file mode 100644 index 000000000..9c59b5b25 --- /dev/null +++ b/cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/ProcessorVersion.java @@ -0,0 +1,57 @@ + + +package gov.nist.secauto.metaschema.cli.processor; + +import gov.nist.secauto.metaschema.core.util.IVersionInfo; + +/** + * Provides version information for this library. + *

+ * This class exposes build-time metadata including version numbers, build + * timestamps, and Git repository information. + */ +public class ProcessorVersion implements IVersionInfo { + + private static final String NAME = "metaschema-java"; + private static final String VERSION = "${project.version}"; + private static final String BUILD_TIMESTAMP = "${timestamp}"; + private static final String COMMIT = "@git.commit.id.abbrev@"; + private static final String BRANCH = "@git.branch@"; + private static final String CLOSEST_TAG = "@git.closest.tag.name@"; + private static final String ORIGIN = "@git.remote.origin.url@"; + + @Override + public String getName() { + return NAME; + } + + @Override + public String getVersion() { + return VERSION; + } + + @Override + public String getBuildTimestamp() { + return BUILD_TIMESTAMP; + } + + @Override + public String getGitOriginUrl() { + return ORIGIN; + } + + @Override + public String getGitCommit() { + return COMMIT; + } + + @Override + public String getGitBranch() { + return BRANCH; + } + + @Override + public String getGitClosestTag() { + return CLOSEST_TAG; + } +} diff --git a/cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/Version.java b/cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/Version.java deleted file mode 100644 index 5b87b3732..000000000 --- a/cli-processor/src/main/java-templates/gov/nist/secauto/metaschema/cli/processor/Version.java +++ /dev/null @@ -1,40 +0,0 @@ - - -package gov.nist.secauto.metaschema.cli.processor; - -import static org.fusesource.jansi.Ansi.ansi; - -import java.io.PrintStream; - -public class Version implements VersionInfo { - - public static final String VERSION = "${project.version}"; - public static final String BUILD_TIMESTAMP = "${timestamp}"; - public static final String COMMIT = "@git.commit.id.abbrev@"; - - public Version() { - } - - @Override - public String getVersion() { - return VERSION; - } - - @Override - public String getBuildTime() { - return BUILD_TIMESTAMP; - } - - @Override - public String getCommit() { - return COMMIT; - } - - @Override - public void generateExtraInfo(PrintStream out) { - out.println(ansi() - .a("Metaschema version ").bold().a(getVersion()).boldOff() - .a(" on commit ").bold().a(getCommit()).boldOff() - .a(" built at ").bold().a( getBuildTime()).reset()); - } -} diff --git a/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/AbstractExitStatus.java b/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/AbstractExitStatus.java index 72ec3c8e0..b37a2d96d 100644 --- a/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/AbstractExitStatus.java +++ b/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/AbstractExitStatus.java @@ -13,6 +13,9 @@ import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +/** + * Records information about the exit status of a CLI command. + */ public abstract class AbstractExitStatus implements ExitStatus { private static final Logger LOGGER = LogManager.getLogger(AbstractExitStatus.class); @@ -61,8 +64,8 @@ public ExitStatus withThrowable(@NonNull Throwable throwable) { @Nullable protected abstract String getMessage(); - @Override - public void generateMessage(boolean showStackTrace) { + @Nullable + private LogBuilder getLogBuilder() { LogBuilder logBuilder = null; if (getExitCode().getStatusCode() <= 0) { if (LOGGER.isInfoEnabled()) { @@ -71,24 +74,31 @@ public void generateMessage(boolean showStackTrace) { } else if (LOGGER.isErrorEnabled()) { logBuilder = LOGGER.atError(); } + return logBuilder; + } - if (logBuilder != null) { - if (showStackTrace && throwable != null) { - Throwable throwable = getThrowable(); - logBuilder.withThrowable(throwable); - } + @Override + public void generateMessage(boolean showStackTrace) { + LogBuilder logBuilder = getLogBuilder(); + if (logBuilder == null) { + return; + } - String message = getMessage(); - if (message == null && throwable != null) { - message = throwable.getLocalizedMessage(); - } + boolean useStackTrace = showStackTrace && throwable != null; + if (useStackTrace) { + logBuilder.withThrowable(throwable); + } - if (message != null && !message.isEmpty()) { - logBuilder.log(message); - } else if (showStackTrace && throwable != null) { - // log the throwable - logBuilder.log(); - } + String message = getMessage(); + if (throwable != null && message == null) { + message = throwable.getLocalizedMessage(); + } + + if (message != null && !message.isEmpty()) { + logBuilder.log(message); + } else if (useStackTrace) { + // log the throwable + logBuilder.log(); } } diff --git a/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/CLIProcessor.java b/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/CLIProcessor.java index f03af2c72..3bc4a494f 100644 --- a/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/CLIProcessor.java +++ b/cli-processor/src/main/java/gov/nist/secauto/metaschema/cli/processor/CLIProcessor.java @@ -49,57 +49,81 @@ import edu.umd.cs.findbugs.annotations.Nullable; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; +/** + * Processes command line arguments and dispatches called commands. + */ +@SuppressWarnings("PMD.CouplingBetweenObjects") public class CLIProcessor { private static final Logger LOGGER = LogManager.getLogger(CLIProcessor.class); - @SuppressWarnings("null") + /** + * This option indicates if the help should be shown. + */ @NonNull - public static final Option HELP_OPTION = Option.builder("h") + public static final Option HELP_OPTION = ObjectUtils.notNull(Option.builder("h") .longOpt("help") .desc("display this help message") - .build(); - @SuppressWarnings("null") + .build()); + /** + * This option indicates if colorized output should be disabled. + */ @NonNull - public static final Option NO_COLOR_OPTION = Option.builder() + public static final Option NO_COLOR_OPTION = ObjectUtils.notNull(Option.builder() .longOpt("no-color") .desc("do not colorize output") - .build(); - @SuppressWarnings("null") + .build()); + /** + * This option indicates if non-errors should be suppressed. + */ @NonNull - public static final Option QUIET_OPTION = Option.builder("q") + public static final Option QUIET_OPTION = ObjectUtils.notNull(Option.builder("q") .longOpt("quiet") .desc("minimize output to include only errors") - .build(); - @SuppressWarnings("null") + .build()); + /** + * This option indicates if a strack trace should be shown for an error + * {@link ExitStatus}. + */ @NonNull - public static final Option SHOW_STACK_TRACE_OPTION = Option.builder() + public static final Option SHOW_STACK_TRACE_OPTION = ObjectUtils.notNull(Option.builder() .longOpt("show-stack-trace") .desc("display the stack trace associated with an error") - .build(); - @SuppressWarnings("null") + .build()); + /** + * This option indicates if the version information should be shown. + */ @NonNull - public static final Option VERSION_OPTION = Option.builder() + public static final Option VERSION_OPTION = ObjectUtils.notNull(Option.builder() .longOpt("version") .desc("display the application version") - .build(); - @SuppressWarnings("null") + .build()); + @NonNull - public static final List

+ * This uses the build-in version information. + * + * @param args + * the command line arguments + */ + public CLIProcessor(@NonNull String args) { + this(args, CollectionUtil.singletonMap(COMMAND_VERSION, new ProcessorVersion())); } - public CLIProcessor(@NonNull String exec, @NonNull Map versionInfos) { - this.exec = exec; + /** + * The main entry point for CLI processing. + *

+ * This uses the provided version information. + * + * @param args + * the command line arguments + * @param versionInfos + * the version info to display when the version option is provided + */ + public CLIProcessor(@NonNull String args, @NonNull Map versionInfos) { + this.args = args; this.versionInfos = versionInfos; AnsiConsole.systemInstall(); } @@ -128,8 +169,8 @@ public CLIProcessor(@NonNull String exec, @NonNull Map ver * @return the command name */ @NonNull - public String getExec() { - return exec; + public String getArguments() { + return args; } /** @@ -142,6 +183,12 @@ public Map getVersionInfos() { return versionInfos; } + /** + * Register a new command handler. + * + * @param handler + * the command handler to register + */ public void addCommandHandler(@NonNull ICommand handler) { commands.add(handler); } @@ -186,11 +233,21 @@ private ExitStatus parseCommand(String... args) { return status; } + /** + * Get the root-level commands. + * + * @return the list of commands + */ @NonNull protected final List getTopLevelCommands() { return CollectionUtil.unmodifiableList(commands); } + /** + * Get the root-level commands, mapped from name to command. + * + * @return the map of command names to command + */ @NonNull protected final Map getTopLevelCommandsByName() { return ObjectUtils.notNull(getTopLevelCommands() @@ -203,6 +260,9 @@ private static void handleNoColor() { AnsiConsole.systemUninstall(); } + /** + * Configure the logger to only report errors. + */ public static void handleQuiet() { LoggerContext ctx = (LoggerContext) LogManager.getContext(false); // NOPMD not closable here Configuration config = ctx.getConfiguration(); @@ -214,6 +274,9 @@ public static void handleQuiet() { } } + /** + * Output version information. + */ protected void showVersion() { @SuppressWarnings("resource") PrintStream out = AnsiConsole.out(); // NOPMD - not owner @@ -235,14 +298,12 @@ protected void showVersion() { out.flush(); } - // @SuppressWarnings("null") - // @NonNull - // public String[] getArgArray() { - // return Stream.concat(options.stream(), extraArgs.stream()).toArray(size -> - // new String[size]); - // } - - public class CallingContext { + /** + * Records information about the command line options and called command + * hierarchy. + */ + @SuppressWarnings("PMD.GodClass") + public final class CallingContext { @NonNull private final List